Setter / property injection in Unity without attributes

后端 未结 8 659
星月不相逢
星月不相逢 2020-12-04 15:58

I am working on a project where the Unity framework is used as the IoC container. My question relates to injecting an optional dependency (in this case a logger) into severa

8条回答
  •  有刺的猬
    2020-12-04 16:25

    I am also not a big fan of using attributes but I also don't like the .Configure() method because you're bound to a specific property name and specific value. The way I've found that gives you the most flexibility is to create your own builder strategy.

    I created this simple class that iterates the properties of an object being built up and sets its property values if the type of that property has been registered with the unity container.

    public class PropertyInjectionBuilderStrategy:BuilderStrategy
    {
        private readonly IUnityContainer _unityContainer;
    
        public PropertyInjectionBuilderStrategy(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }
    
        public override void PreBuildUp(IBuilderContext context)
        {
            if(!context.BuildKey.Type.FullName.StartsWith("Microsoft.Practices"))
            {
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(context.BuildKey.Type);
    
                foreach (PropertyDescriptor property in properties)
                {
                    if(_unityContainer.IsRegistered(property.PropertyType)
                       && property.GetValue(context.Existing) == null)
                    {
                        property.SetValue(context.Existing,_unityContainer.Resolve(property.PropertyType));
                    }
                }
            }
        }
    }
    

    You register your BuilderStrategy by creating a UnityContainerExtension. Here is an example:

    public class TestAppUnityContainerExtension:UnityContainerExtension
    {
        protected override void Initialize()
        {
            Context.Strategies.Add(new PropertyInjectionBuilderStrategy(Container), UnityBuildStage.Initialization);
        }
    }
    

    That gets registered with the Unity container as such:

    IUnityContainer container = new UnityContainer();
    container.AddNewExtension();
    

    Hope this helps,
    Matthew

提交回复
热议问题