Unity 2.0: How to use Resolve with ResolverOverride?

前端 未结 3 1128
借酒劲吻你
借酒劲吻你 2020-12-12 14:47

I started doing more and more work with Unity. I notice that Resolver method takes a params argument ResolverOverride.

Can someone give me an exam

相关标签:
3条回答
  • 2020-12-12 15:20

    Just in case someone is interested, I have made an extension method that makes the syntax for resolving using ParameterOverride a little easier to read. The method is as follows:

    public static class UnityExtensions
    {
        public static T Resolve<T>(this IUnityContainer container, object parameterOverrides)
        {
            var properties = parameterOverrides
                .GetType()
                .GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var overridesArray = properties
                .Select(p => new ParameterOverride(p.Name, p.GetValue(parameterOverrides, null)))
                .Cast<ResolverOverride>()
                .ToArray();
            return container.Resolve<T>(null, overridesArray); //null needed to avoid a StackOverflow :)
        }
    }
    

    With this, you can rewrite the ParameterOverride example as follows:

    var service = container.Resolve<IConcreteService>(new {val=3});
    

    I hope this is useful for someone...

    0 讨论(0)
  • 2020-12-12 15:24

    As you have noticed this is a new (and really cool feature) of the Unity 2. This feature let you

    • pass parameters to constructor in the moment when you resolve the class. In unity 1 you can set only one value in the moment when you register type via new InjectionConstructor(...)

    There is ParameterOverride : ResolverOverride

    A ResolverOverride class that lets you override a named parameter passed to a constructor.

    • same for dependencies with DependencyOverride : ResolverOverride

    A class that overrides the value injected whenever there is a dependency of the given type, regardless of where it appears in the object graph.

    • same for properties with PropertyOverride : ResolverOverride

    A ResolverOverride that lets you override the value for a specified property.

    Example

    using System;
    using Microsoft.Practices.Unity;
    
    namespace ConsoleApplication1 {
        class Program {
            static void Main(string[] args) {
    
                var container = new UnityContainer();
    
                //ParameterOverride example
    
                container.RegisterType<IConcreteService, ConcreteService>(
                    new InjectionConstructor(7) //Old way to pass value to constructor - not flexible. 
                                                //All resolved (without override which appears only in unity 2.0) classes will have val=7
                    );
    
                var service0 = container.Resolve<IConcreteService>();
                Console.WriteLine(service0.Val); //prints 7
    
                var service = container.Resolve<IConcreteService>(new ParameterOverride("val", 3));
                Console.WriteLine(service.Val); // prints 3
    
                var service2 = container.Resolve<IConcreteService>(new ParameterOverride("val", 5));
                Console.WriteLine(service2.Val); // prints 5
    
                Console.ReadLine();
    
                //DependencyOverride example
    
                var b0 = container.Resolve<B>(new DependencyOverride<IConcreteService>(new ConcreteService(42)));
                Console.WriteLine(b0.Service.Val); //print 42
                Console.WriteLine(b0.Service1.Val); //print 42
    
                var b = container.Resolve<B>(new DependencyOverride<IConcreteService>(new ConcreteService(-42)));
                Console.WriteLine(b.Service.Val); // print -42
                Console.WriteLine(b.Service1.Val); // print -42
    
                Console.ReadLine();
    
                //PropertyOverride example 
    
                var b1 = container.Resolve<B>(new PropertyOverride("Service", new ConcreteService(42)), 
                    new PropertyOverride("Service1", new ConcreteService(-42)));
                Console.WriteLine(b1.Service.Val); //print 42
                Console.WriteLine(b1.Service1.Val); //print -42
    
                Console.ReadLine();
    
    
    
            }
        }
    
        public interface IConcreteService {
            int Val { get; set; }
        }
        public class ConcreteService : IConcreteService {
    
            public int Val { get; set; }
    
            public ConcreteService(int val) {
                Val = val;
            }
        }
    
        public class B {
            [Dependency]
            public IConcreteService Service{ get; set; }
    
            [Dependency]
            public IConcreteService Service1 { get; set; }
    
        }
    }
    

    Have no idea why does Google keeps silent about that.

    Quotes are from Unity source code xml docs.

    0 讨论(0)
  • 2020-12-12 15:28

    Just to add my 2c. You can just add a ParameterOverrides like so:

    Container.Resolve<IConcreteService>(new ParameterOverrides
    {                                                                                   
      {"val", 42}
    });
    
    0 讨论(0)
提交回复
热议问题