繁体   English   中英

Unity依赖关系无法解决任务

[英]Unity dependency not resolving in task

我不确定如何解决目前的情况。 我正在尝试创建一个任务:

public class whatever
{
    [Dependency]
    public IReportingBL ReportingBL { get; set; }

    private whatever()
    {
    ...task factory creation, etc.
    }

    private readonly static Lazy<whatever> _instance = new Lazy<whatever>(() => new whatever());

    public static whatever Instance { get { return _instance.Value; }

    public Task GetStuff()
    {
        return _taskFactory.StartNew(() =>
        {
            return ReportingBL.Method1;
        });
    }
}

ReportingBL无法解决。 如果我在线程内创建一个ReportingBL的新实例,那么它下面的层将无法解析。

在这种情况下,我该如何团结起来工作?

您正在应用Singleton设计模式 这是一种被某些人皱眉并视为反模式的模式。 在依赖注入术语中,可以将Singleton模式视为环境上下文 ,这是在依赖注入上下文中几乎不应使用的模式。

Singleton设计模式不适用于依赖注入,因为:

  • 使用依赖注入,由应用程序的“ 合成根”控制创建实例和对其进行缓存。 而不是实例本身。
  • 让使用者依赖于公共Instance字段,会导致使用者违反“依赖倒置原则”,并且不允许实例被替换,嘲笑,修饰或拦截。 这阻碍了应用程序的可维护性和可测试性。

此外,在您的代码中,我看不到对Unity DI框架的任何调用。 请记住,DI容器并不是一种神奇的工具,它不会允许类“自己”进行初始化。 在代码中,您whatever直接更新whatever Unity不参与其中。 Unity(或任何与此相关的DI库)只能在对象控制下自动连接对象。 换句话说,您将必须调用container.Resolve<whatever>()来使Unity建立实例。

尽管您可以从Lazy<T>工厂委托中调用container.Resoolve ,但这会迫使类依赖于容器本身,这通常称为Service Locator反模式

相反,我建议对您的设计进行以下更改:

  1. 使用构造函数注入而不是属性注入。 属性注入导致时间耦合
  2. 使“合成根”和负责连接对象图的容器成为可能。
  3. 远离Singleton设计模式; 请改用容器的Singleton Lifestyle。

这将导致以下代码:

public interface IWhatever
{
    Task GetStuff();
}

public class Whatever : IWhatever
{
    private readonly IReportingBL reportingBL;

    public whatever(IReportingBL reportingBL) {
        this.reportingBL = reportingBL;
    }

    public Task GetStuff() {
        return _taskFactory.StartNew(() => {
            return ReportingBL.Method1;
        });
    }
}

// Some consumer of whatever
public class MyController : Controller
{
    private readonly IWhatever whatever;

    public MyController(IWhatever whatever) {
        this.whatever = whatever;
    }

    public ActionResult Index() {
        return View(this.whatever.GetStuff());
    }
}

在您的合成根目录中,您可以按以下方式配置类:

var container = new UnityContainer();

container.RegisterType<IReportingBL, ReportingBL>(
    new ContainerControlledLifetimeManager());
container.RegisterType<IWhatever, Whatever>(
    new ContainerControlledLifetimeManager());

var controller = container.Resolve<MyController>();

controller.Index();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM