Showing posts with label Unity. Show all posts
Showing posts with label Unity. Show all posts

Wednesday, 23 January 2013

Configuring Unity container at runtime

 
1. Some business logic first
 
    public interface ILogger
    {
        void Log(string information);
    }
    
    public class Logger : ILogger
    {
        public void Log(string information)
        {
            Console.WriteLine(information);
        }
    }
 
    public class Employee
    {
        public string FirstName { getset; }
 
        public string LastName { getset; }
 
        public DateTime DOB { getset; }
 
        public Guid ID { getset; }
    }
 
    public interface IEmployeeService
    {
        [BeforeHandler]
        [AfterHandler1]
        [AfterHandler2]        
        bool AddOrUpdate(Employee employee);
 
        [BeforeHandler]
        [AfterHandler1]
        [AfterHandler2]
        Employee Get(Guid id); 
 
        [BeforeHandler]
        [AfterHandler1]
        [AfterHandler2]          
        bool Delete(Guid id);
    }
 
    public class EmployeeService : IEmployeeService
    {
        public EmployeeService(ILogger logger)
        {
            this.Logger = logger;
        }
 
        private ILogger Logger { getset; }
        #region IEmployeeService Members
 
        public bool AddOrUpdate(Employee employee)
        {
            this.Logger.Log("AddOrUpdate called");
 
            return true;
        }
 
        public Employee Get(Guid id)
        {
            this.Logger.Log("Get called");
 
            return new Employee();
        }
 
        public bool Delete(Guid id)
        {
            this.Logger.Log("Delete called");
 
            return true;
        }
 
        #endregion
    }
 
2. Now Add some handlers/Matching rules 

public class AlwaysMatchingRule : IMatchingRule
    {
        public bool Matches(System.Reflection.MethodBase member)
        {
            return true;
        }
    }
 
    public class BeforeHandler : ICallHandler
    {
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            Console.WriteLine("CallHandler '{0}' will now execute '{1}', Order '{2} "this.GetType().Name, input.MethodBase.Name, this.Order);
 
            return getNext().Invoke(input, getNext);
        }
 
        public int Order { getset; }
    }
 
    public class AfterHandler1 : ICallHandler
    {
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            var result =  getNext().Invoke(input, getNext);
 
            Console.WriteLine("CallHandler '{0}' executed '{1}', Order '{2}' "this.GetType().Name, input.MethodBase.Name, this.Order);
 
            return result;
        }
 
        public int Order { getset; }
    }
 
    public class AfterHandler2 : ICallHandler
    {
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            var result = getNext().Invoke(input, getNext);
 
            Console.WriteLine("CallHandler '{0}' executed '{1}', Order '{2}' "this.GetType().Name, input.MethodBase.Name, this.Order);
 
            return result;
        }
 
        public int Order { getset; }
    }
 
    public class BeforeHandlerAttribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        {
            return new BeforeHandler();
        }
    }
 
    public class AfterHandler1Attribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        {
            return new AfterHandler1();
        }
    }
 
    public class AfterHandler2Attribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        {
            return new AfterHandler2();
        }
    } 
 
3. Now configuring container 

        static void Main(string[] args)
        {
            //case 1: simple configuration
            IUnityContainer container1 = new UnityContainer()
                                        .RegisterType<ILogger, Logger>()
                                        .RegisterType<IEmployeeService, EmployeeService>(new InjectionConstructor(typeof(ILogger)));

            //case 2: Here ILogger will be resolved automatically, not need to inject
            IUnityContainer container2 = new UnityContainer()
                                        .RegisterType<ILogger, Logger>()
                                        .RegisterType<IEmployeeService, EmployeeService>();

            //case 3: Different way(obselete) of injection
            IUnityContainer container3 = new UnityContainer()
                                        .RegisterType<ILogger, Logger>()
                                        .RegisterType<IEmployeeService, EmployeeService>()
                                        .Configure<InjectedMembers>()
                                        .ConfigureInjectionFor<EmployeeService>(
                                        new InjectionConstructor(typeof(ILogger))).Container;

            //case 4: Configuring with Policies->Rules->CallHandlers and 
            IUnityContainer container4 = new UnityContainer();

            container4.AddNewExtension<Interception>();
            
            container4
                        .Configure<Interception>()
                            .AddPolicy("Trace")
                                .AddMatchingRule("AlwaysMatchingRule")
                                .AddCallHandler("BeforeHandler")
                                .AddCallHandler("AfterHandler1")
                                .AddCallHandler("AfterHandler2").Interception.Container
                        .RegisterType<IMatchingRule, AlwaysMatchingRule>("AlwaysMatchingRule")
                        .RegisterType<ICallHandler, BeforeHandler>("BeforeHandler", new InjectionProperty("Order", 1))
                        .RegisterType<ICallHandler, AfterHandler1>("AfterHandler1", new InjectionProperty("Order", 2))
                        .RegisterType<ICallHandler, AfterHandler2>("AfterHandler2", new InjectionProperty("Order", 3))
                        .RegisterType<ILogger, Logger>()
                        .RegisterType<IEmployeeService, EmployeeService>()
                        .Configure<Interception>()
                        .SetInterceptorFor<IEmployeeService>(new TransparentProxyInterceptor());

            //case 5: Using handler attributes - simplest of configuration
            IUnityContainer container5 = new UnityContainer();

            container5.AddNewExtension<Interception>();
            container5
                        .Configure<Interception>()
                            .SetDefaultInterceptorFor<IEmployeeService>(new TransparentProxyInterceptor())
                        .Container
                        .RegisterType<ILogger, Logger>()
                        .RegisterType<IEmployeeService, EmployeeService>();

            ExerciseAllServices(container1.Resolve<IEmployeeService>());
            ExerciseAllServices(container2.Resolve<IEmployeeService>());
            ExerciseAllServices(container3.Resolve<IEmployeeService>());
            ExerciseAllServices(container4.Resolve<IEmployeeService>());
            ExerciseAllServices(container5.Resolve<IEmployeeService>());
 
            container1.Dispose();
            container2.Dispose();
            container3.Dispose();
            container4.Dispose();
        }

        private static void ExerciseAllServices(IEmployeeService service)
        {
            service.AddOrUpdate(null);
            service.Get(Guid.Empty);
            service.Delete(Guid.Empty);
            Console.WriteLine("-----------------------------------------------");
        } 
 
 
Some good References
http://blogsprajeesh.blogspot.in/2009/12/unity-application-block-interceptor.html 
http://msdn.microsoft.com/en-us/library/ff660871%28v=pandp.20%29.aspx 
http://msdn.microsoft.com/en-us/library/dd203208.aspx 
http://msdn.microsoft.com/en-us/library/ff647107.aspx 

Wednesday, 4 July 2012

Split unity configuration file

For maintenance reasons, it is better to split a 'BIG' unity configuration into multiple files. One such way to do this is

1. Let us imagine we need to split into two files, so your root config file will look like below

<configSections>
    <section name="unitySection1
          type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
          Microsoft.Practices.Unity.Configuration"/>
    <section name="unitySection2
          type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
          Microsoft.Practices.Unity.Configuration"/>
</configSections>

<unitySection1 configSource="unity1.config" />
<unitySection2 configSource="unity2.config" /> 
 
2. And your individual unity files will look like below(see the highlighted section that 'unity' tag becomes 'unitySection1')
 
   <unitySection1>
       <container /> 
   </unitySection1>
 
   <unitySection2
       <container />
   </unitySection2>
 
3. Load the separate configuration files into Container


    UnityContainer.LoadConfiguration - will adds up the container details, so we just need to call it twice


 private void Initialise()
 {
   string[] unitySections = new string[] {"unitySection1", "unitySection2"};
  
   IUnityContainer container = new UnityContainer(); 
 
   foreach(var section in unitySections)
   {
      var configuration = ConfigurationManager.OpenExeConfiguration(path);
 
      var unitySection = (UnityConfigurationSection)configuration.
                          GetSection(section);
        
      container.LoadConfiguration(unitySection);
    }
 }
 
reference link