当前位置:  开发笔记 > 运维 > 正文

Unity中的Setter/property注入没有属性

如何解决《Unity中的Setter/property注入没有属性》经验,为你挑选了4个好方法。

我正在开发一个项目,其中Unity框架用作IoC容器.我的问题涉及使用property-或setter注入将可选依赖项(在本例中为记录器)注入到几个类中.

我不想使用这些可选的依赖项来混乱所有类的构造函数,但是我找不到在Unity中处理它的好方法.根据MSDN文档,您可以通过向属性添加属性来实现此目的:

private ILogger logger; 

[Dependency]
public ILogger Logger
{
get { return logger; }
  set { logger = value; }
}

我觉得这很难看.在StructureMap中,可以执行以下操作来设置给定类型的所有属性:

SetAllProperties(policy => policy.OfType());

有谁知道在Unity中是否有可能做类似的事情?

编辑:

Kim Major建议使用这种方法,也可以通过代码实现.

我会对如何自动为所有匹配属性执行此操作的示例感兴趣.



1> t3mujin..:

我也不喜欢这些属性

您可以使用unity容器的Configure方法完成所有操作:

首先注册类型

unityContainer.RegisterType(
                     new ContainerControlledLifetimeManager());

如果你有多个构造函数,你必须这样做,所以Unity调用无参数构造函数(如果没有设置Unity将用于最胖的构造函数)

unityContainer.Configure()
                            .ConfigureInjectionFor(
                                new InjectionConstructor()); 

设置属性依赖

unityContainer.Configure()
                    .ConfigureInjectionFor(
                         new InjectionProperty(
                             "SomePropertyName",
                                new ResolvedParameter()));

配置方法依赖

unityContainer.Configure()
                    .ConfigureInjectionFor(
                        new InjectionMethod(
                            "SomeMethodName",
                            new ResolvedParameter()));



2> Matthew..:

我也不是使用属性的忠实粉丝,但我也不喜欢这个.Configure()方法,因为你绑定了特定的属性名称和特定值.我发现的方式为您提供了最大的灵活性,就是创建自己的构建器策略.

我创建了这个简单的类,它迭代正在构建的对象的属性,并在已使用unity容器注册该属性的类型时设置其属性值.

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));
                }
            }
        }
    }
}

BuilderStrategy通过创建一个注册您UnityContainerExtension.这是一个例子:

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

这是在Unity容器中注册的:

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

希望这会有所帮助,
马修



3> 小智..:

您发布的原始示例看起来非常麻烦,但您可以使用此类自动实现的属性来帮助清理该代码:

[Dependency]
public ILogger Logger { get; set; }



4> 小智..:

使用Unity 2.1,这也可以:

var container = new UnityContainer()
            .RegisterType()
            .RegisterType(
                                new InjectionProperty("Logger", new ResolvedParameter()));

SomeImplementaion类的注入属性正好

public ILogger Logger { get; set; }

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有