C# 任务中未解决统一依赖关系

C# 任务中未解决统一依赖关系,c#,asp.net,dependency-injection,task,unity-container,C#,Asp.net,Dependency Injection,Task,Unity Container,我不确定如何解决我目前的状况。我正在尝试创建一个任务: public class whatever { [Dependency] public IReportingBL ReportingBL { get; set; } private whatever() { ...task factory creation, etc. } private readonly static Lazy<whatever> _instance

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

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;
        });
    }
}
公共类
{
[依赖性]
公共IReportingBL ReportingBL{get;set;}
二等兵
{
…任务工厂创建等。
}
private readonly static Lazy _instance=new Lazy(()=>newwhich());
公共静态任意实例{get{return _Instance.Value;}
公共任务GetStuff()
{
return\u taskFactory.StartNew(()=>
{
返回报告BL.Method1;
});
}
}
ReportingBL无法解析。如果我在线程内创建了ReportingBL的新实例,那么它下面的层将无法解析

在这种情况下,我如何让unity工作?

您正在应用。这是一种不受欢迎的模式,有些人认为它是反模式。在依赖注入术语中,单例模式可以被视为一种模式,这是一种几乎不应该在依赖注入上下文中使用的模式

Singleton设计模式不能很好地与依赖项注入配合使用,因为:

  • 通过依赖项注入,由应用程序控制创建实例和缓存实例,而不是实例本身
  • 让使用者依赖于公共
    实例
    字段,会导致使用者违反依赖倒置原则,并禁止替换、模拟、修饰或拦截实例。这会妨碍应用程序的可维护性和可测试性
此外,在您的代码中,我没有看到任何对Unity DI框架的调用。请记住,DI容器并不是一个神奇的工具,它允许类“由它们自己”初始化。在您的代码中,您可以直接创建
任何内容;Unity不参与其中。Unity(或任何DI库)只有在对象处于控制状态时,才能自动连接对象。换句话说,您必须调用Unity的
container.Resolve()
,才能构建实例

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

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

  • 使用构造函数注入而不是属性注入。属性注入会导致错误
  • 使合成根和容器负责连接对象图
  • 远离单例设计模式;改用容器的单例生活方式
  • 这将产生以下代码:

    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());
        }
    }
    
    在composition根目录中,可以按如下方式配置类:

    var container = new UnityContainer();
    
    container.RegisterType<IReportingBL, ReportingBL>(
        new ContainerControlledLifetimeManager());
    container.RegisterType<IWhatever, Whatever>(
        new ContainerControlledLifetimeManager());
    
    var controller = container.Resolve<MyController>();
    
    controller.Index();
    
    var container=newunitycontainer();
    container.RegisterType(
    新的ContainerControlled LifetimeManager());
    container.RegisterType(
    新的ContainerControlled LifetimeManager());
    var controller=container.Resolve();
    controller.Index();
    
    如何创建
    whatever
    类?能否显示该类的代码?如果从多个线程访问变量,则需要同步对该变量的访问。@Servy我不需要ReportingBL,只需要在线程中。如果我在线程中声明新的ReportingBL,则其子线程也不会解析。如果我需要管理它所产生的所有线程,这就行不通了,是吗?@Shawn:我不知道你的意思。请注意,一般来说,你的应用程序代码不应该处理线程和并行性,你应该防止在应用程序中从一个线程移动到另一个线程。这是基础结构逻辑hat应该和应用程序代码分开,放在应用程序的合成根目录中。Anywhere类的目的是管理GetStuff创建的线程。根据您的回答,我将在每个需要调用它的类中创建一个新实例。我为我的singleton声明了一个接口,并使用了unityssingleton控件。我很困惑,因为我所有的配置都在web.config中。谢谢你的帮助。