Thursday, April 20, 2017

Rules Based Engine using Tuples

Dynamic Rules Defined Using Tuple

  1. Input: Define Rules Case Conditions
  2. Output :Define Results based on Rules case conditions

       

          
   
    class Program
    {
        static void Main(string[] args)
        {
            var options = GenerateRulesBasedResults(true, false, false, false, true);
            foreach (var option in options)
            {
                Console.WriteLine (option.ToString());
                /* Ford
                 * BMW
                 * Mercedes
                 */
            }
            Console.Read();
        }
        public static List<CarSale> GenerateRulesBasedResults(bool isCruiseControl, bool isAutomatic, 
                                                               bool isUnderWarranty, bool isOnSale, bool isOnRoadOffSale)
        {
            List<CarSale> options;
            Results.TryGetValue(Tuple.Create(isCruiseControl, isAutomatic, isUnderWarranty, isOnSale, isOnRoadOffSale), out options);
            return options;
        }

        //I/P Rule Case Condition variant
        private static readonly Tuple<bool, bool, bool, bool, bool> RuleCaseCondition1 = Tuple.Create(true, false, false, false, true);
        private static readonly Tuple<bool, bool, bool, bool, bool> RuleCaseCondition2 = Tuple.Create(false, true, false, false, true);       

        //O/P Rule based results.
        private static readonly Dictionary<Tuple<bool, bool, bool, bool, bool>, List<CarSale>> Results =
            new Dictionary<Tuple<bool, bool, bool, bool, bool>, List<CarSale>>
        {
                { RuleCaseCondition1, new List<CarSale> {   CarSale.Ford , CarSale.BMW, CarSale.Mecedes} },

                { RuleCaseCondition2, new List<CarSale> {   CarSale.Suzuki , CarSale.Mazda} },
        };

        public enum CarSale
        {
            Honda,
            BMW,
            Mazda,
            Suzuki,
            Mecedes,
            Wolkswagen,
            Ford
        }

  

  
       
 

Tuesday, April 11, 2017

Sitecore MVC best practice Avoid Multiple types were found that match the controller

Scenario


Pre- production cleanup and performance improvement. In terms of security and performance optimization, sitecore logs, iis logs, http sys logs or event logs are best place to look upon. It give detailed behavour of application in terms of errors, redundant calls and other user specific details that are security threats. Having said that keeping production environment clean is good for application overall health. Below is the one of the example that we may ignore. This can be viewed in event logs mostly.


Event Log

Multiple types were found that match the controller named 'Authentication'. This can happen if the route that services this request ('sitecore/shell/api/sitecore/{controller}/{action}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter. The request for 'Authentication' has found the following matching controllers: Sitecore.Controllers.AuthenticationController My.MVC.Areas.MyAPI.Controllers.Api.AuthenticationController at System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces) at System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) at System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) at Sitecore.Mvc.Controllers.SitecoreControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) at System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) at Sitecore.Mvc.Routing.RouteHandlerWrapper.GetHttpHandler(RequestContext requestContext) at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) at System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

BottomLine

Never use sitecore or .net intrinsic names for controller

Sunday, April 9, 2017

Add Sitecore AD Membership Provider at runtime

Before you refer this blog, refer this blogpost
https://santoshpoojari.blogspot.com.au/2017/03/sitecore-active-directorysitecoreadmemb.html

I have taken more generic approach to add this. I have refined the above method with c# generic constraint.


Things to be taken care.      

We cannot use below Providers add due: Exception Details: System.NotSupportedException: Collection is read-only.

//Membership.Providers.Add(provider);
Therefore we should use utility class that give extension method AddTo.

http://stackoverflow.com/questions/1432508/programmatically-adding-a-membership-provider

Generic Membership Provider

  
 public static void InitialiseProviders <T>(T provider, string providerName, NameValueCollection providerConfiguration) where T : MembershipProvider
        {
            provider.Initialize(providerName, providerConfiguration);
            provider.AddTo(Membership.Providers);
            //We cannot use below Providers add due: Exception Details: System.NotSupportedException: Collection is read-only.
            //Membership.Providers.Add(provider);
        }

Utility Extension Method

public static class ProviderUtil
{
    static private FieldInfo providerCollectionReadOnlyField;

    static ProviderUtil()
    {
        Type t = typeof(ProviderCollection);
        providerCollectionReadOnlyField = t.GetField("_ReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
    }

    static public void AddTo(this ProviderBase provider, ProviderCollection pc)
    {
        bool prevValue = (bool)providerCollectionReadOnlyField.GetValue(pc);
        if (prevValue)
            providerCollectionReadOnlyField.SetValue(pc, false);

        pc.Add(provider);

        if (prevValue)
            providerCollectionReadOnlyField.SetValue(pc, true);
    }
}


Initialize the LDap AD Configuration and call the generic method

 public static NameValueCollection LdapSitecoreProviderConfiguration
        {
            get {

                 NameValueCollection config = new NameValueCollection();                                 
                 config["type"] = "LightLDAP.SitecoreADMembershipProvider";
                 config["name"] = "SomeProviderName";

                 config["connectionStringName"] = "LDAPConnString";
                 config["applicationName"] = "sitecore";
 
                 config["connectionUsername"] = ConfigurationManager.AppSettings["AppSettingKeys-UserName"];
                 config["connectionPassword"] = ConfigurationManager.AppSettings["AppSettingKeys-Password"];
 
                 config["minRequiredPasswordLength"] = "1";
                 config["minRequiredNonalphanumericCharacters"] = "0";
                 config["requiresQuestionAndAnswer"] = "false";
 
                 config["requiresUniqueEmail"] = "false";
                 config["connectionProtection"] = "secure";
 
                 config["attributeMapUsername"] = "sAMAccountName";
                 config["enableSearchMethods"] = "true";
 
                 config["customFilter"] = "(memberOf=Your org custom filter)";
                 return config;
            }
        }
InitialiseProviders(new SitecoreADMembershipProvider(), "someldapName", xyz.LdapSitecoreProviderConfiguration);

Saturday, April 1, 2017

Devops- VSO and Git!

Azure :Continuous Delivery Preview

Donovan Brown Channel 9 Session

Devops Systematic Integration 
  • Build -CI 
  • Deploy Release -CD
Helped me create first end to end devops CI and CD pipeline using continuous delivery preview.

https://channel9.msdn.com/events/Visual-Studio/Visual-Studio-2017-Launch/WEB-105

I face one issue with nuget restore and it is because of this error causing constant issue.
http://stackoverflow.com/questions/32254439/nuget-packages-are-missing
After configuring continuous delivery with resource group and app service plan. It asks for repository and setup build and release pipeline by itself. In fact zero configuration.

























Options : Multiple configuration To queue parallel build on different agents


Even you can apply above magic directly from powershell script.

Create New: Yo team



Update existing CI and CD:Yo team/pipeline

Build Agents

  • No physical controller
  • Work side by side with XAML
  • Agents are XCOPY deployed and auto updated from server
  • Agent pool and collection assign to machine Agent

Gear Icon

Important Information
  • Download agents
  • Unblock the folder
  • Run ConfigureAgent.Ps1
  • Copy Team foundation server url
  • Give working folder name
  • Run as window service or interactive mode

Note:
  • Agent Capability in relation with Build General Tab -> Demand.
  • Demand can be used to run build on Premise agent or cloud agent.