Implementing a custom strategy - Solved with alternative solution

Oct 20, 2011 at 2:24 PM
Edited Oct 20, 2011 at 2:30 PM

Hi all,

I am looking to implement a custom strategy with the ability to resolve non-registered interfaces with the knowledge of concrete implementations being used earlier in the buildup.

 

For example:

 

        interface IMyInterface
        {
            string Value { get; }
        }

        class ImplementationA : IMyInterface
        {
            public string Value { get { return "A"; } }
        }

        class ImplementationB : IMyInterface
        {
            public string Value { get { return "B"; } }
        }

        class NestedParam
        {
            public IMyInterface MyInterface { get; set; }

            public NestedParam(IMyInterface myInterface)
            {
                MyInterface = myInterface;
            }
        }

        class Tester
        {
            public NestedParam NestedParam { get; set; }

            public IMyInterface MyInterface { get; set; }

            public Tester(IMyInterface myInterface, NestedParam nestedParam)
            {
                MyInterface = myInterface;
                NestedParam = nestedParam;
            }
        }

        class Resolver
        {
            public static void Main()
            {
                using (IUnityContainer unityContainer = new UnityContainer())
                {
                    unityContainer.RegisterType<Tester>(new InjectionConstructor(typeof(ImplementationA), typeof(NestedParam)));

                    Tester tester = unityContainer.Resolve<Tester>();
                    Debug.Assert(tester.MyInterface.Value == "A");
                    Debug.Assert(tester.NestedParam.MyInterface.Value == "A");
Debug.Assert(tester.MyInterface == tester.NestedParam.MyInterface);
  } } }

 

As I have specified the first IMyInterface to be injected as a typeof(ImplementationA) at the root of the buildup, I would like the functionality for it to automatically resolve the IMyInterface of NestedParam to the same object (If no InjectionConstructor is specified for NestedParam).

 

I have attempted this, through creating my own implementation of DynamicMethodConstructorStrategy, and adding a resolver override on the TearDown of each object, however I think I am misunderstanding some of the fundamentals, for example context.Existing in the TearDown isn't an implementation of the object as I would have expected.

 

If anyone has any ideas of how this can be achieved, or wishes to shed some light on my misunderstanding, it would be very much appreciated :)

 

Luke

Oct 21, 2011 at 9:02 AM

There is a number of technical solutions to your problem, but first of all: Why do you want to reuse an implementation of IMyInterface in classes Tester and NestedParam? That is redundant information that might have unexpected side effects. Wouldn't it be easier to implement something like this:

    class Tester
    {
        public NestedParam NestedParam { get; set; }

        public IMyInterface MyInterface
        {
            get
            {
                return NestedParam.MyInterface;
            }
            set
            {
                NestedParam.MyInterface = value;
            }
        }

        public Tester(NestedParam nestedParam)
        {
            NestedParam = nestedParam;
        }
    }

Technical answers to your question:

You can use the InjectionFactory to specify how Tester is constructed (resolve IMyInterface first and reuse it to construct NestedParam and Tester via container.Resolve(new ParameterOverride(...))

You can register IMyInterface as a singleton (might not be what you want if you don't want to share one instance of IMyInterface across the entire application)

You can use child containers where different implementations of IMyInterface are registered (var child = container.CreateChildContainer(); child.RegisterType<IMyInterface, ImplementationA>(); var anotherChild = container.CreateChildContainer(); anotherChild.RegisterType...),

although I find the use of nested containers somewhat non-intuitive and clumsy.

Oct 21, 2011 at 9:26 AM

Hi Damien,

I too was thinking last night that using an InjectionFactory is probably the best way to accomplish what I want (I try to avoid using child containers as I feel the same as you), I do however like your code example for simple situations such as the one I demonstrated.

I think I will probably use a DependencyOverride instead of ParameterOverride though, so that I can resolve any implementations of that type anywhere in the nested object graph to the same resolved object.

Thanks a lot for looking at this Damien, another view on things always helps.

Regards,

Luke