使用Unity进行属性依赖注入的正确方法 [英] The right way to do property dependency injection using Unity

查看:221
本文介绍了使用Unity进行属性依赖注入的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要依赖注入的类。由于该类已经是另一个抽象的实现,并且其兄弟实现可能不共享相同的依赖关系,因此我尝试使用属性注入而不是构造函数注入。

I have a class that needs a dependency injecting. As the class is already an implementation of another abstraction, and its 'sibling' implementations may not share the same dependencies, I am attempting to use property injection and not constructor injection.

(所有这些类/接口名称仅用于说明目的)

(All these classes/interface names are just for illustrative purposes)

我的 IProvider 抽象:

public interface IProvider
{
    void ProviderMethod();
}

我的 IProvider 实现(我要注入的IData依赖项)

public class ProviderClass : IProvider
{
    // How do I inject this dependency?
    [Dependency]
    public IData data { get; set; }

    public void ProviderMethod()
    {
        // Can't do this as data == null!
        data.DataMethod();
    }
}

另一个 IProvider 实现(显示不具有相同依赖性的示例):

Another IProvider implementation (example to show that it doesn't have the same dependencies):

public class AnotherProviderClass : IProvider
{
    // No data dependency here!!

    public void ProviderMethod()
    {
        // Do other stuff here
    }
}

示例 IData 抽象和实现:

public interface IData
{
    void DataMethod();
}

public class DataClass : IData
{
    public void DataMethod();
}

我需要知道的是:如何成功注入属性依赖项(使用Unity(我选择的IOC容器)将 IData )添加到 ProviderClass 中?

What I need to know is: How do I successfully inject the property dependency (IData) into ProviderClass using Unity (my IOC container of choice)?

我尝试了所有方式的Unity注册选项(RegisterType,RegisterInstance,Resolve ...),但是我注入的属性始终以NULL结尾。我想这样做是正确的,而不仅仅是强迫随机代码进入,直到它可以正常工作为止。

I have tried all manner of Unity registering options (RegisterType, RegisterInstance, Resolve...) but my injected property always ends up as NULL. I want to do this right and not just force random code in until it just manages to work.

或者有更好的方法将(可选)依赖项注入兄弟

Or is there a better way of injecting (optional) dependencies into 'sibling' classes?

偶然地,我最初的IProvider实现是通过抽象工厂创建的,所以也许这可能是我应该将IData依赖重点放在另一个区域吗? p>

Incidentally, my initial IProvider implementations are created via an abstract factory, so maybe that might be another area I should focus this IData dependency on(?)

推荐答案

您仍应使用构造函数注入,因为依赖项几乎永远不会是可选的

You should still use constructor injection because dependencies should hardly ever be optional.

您正试图防止构造函数过度注入 IProviderFactory 实现,您可能不想将容器注入工厂,以防止掉入服务定位器反模式

You are trying to prevent constructor over-injection in the IProviderFactory implementation, and you probably don't want to inject the container into your factory to prevent falling into the Service Locator anti-pattern.

如果您定义您的 IProviderFactory 实现在您的组成根目录内,即使您注入了容器,您也会阻止自己执行Service Locator,因为服务定位器与技巧无关

If however you define your IProviderFactory implementation INSIDE your Composition Root, you prevent yourself from doing Service Locator, even though you inject the container, since Service Locator is not about mechanics.

因此,您应将 ProviderFactory 实现定义为尽可能接近您的Unity配置,并且应该看起来像这样:

So you should define your ProviderFactory implementation as close to your Unity configuration as possible and it should look something like this:

public class ProviderFactory : IProviderFactory
{
    private readonly Dictionary<string, Type> providerTypes;
    private readonly Container container;

    public ProviderFactory(Dictionary<string, Type> providerTypes, 
        Container container) {
        this.providerTypes = providerTypes;
        this.container = container;
    }

    public IProvider CreateProvider(string name) {
        return (IProvider)this.container.Resolve(this.providerTypes[name]);
    }
}

此实现可以在Unity中注册为单例。这样一来,您就不必在不使用Service Locator的情况下,将构造函数过度注入您的工厂。

This implementation can be registered as singleton in Unity. This saves you from having to do constructor over-injection into your factory, while staying away from Service Locator.

这篇关于使用Unity进行属性依赖注入的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆