【问题标题】:Dependency injection with Unity in 3 tier architecture在 3 层架构中使用 Unity 进行依赖注入
【发布时间】:2018-06-25 22:57:55
【问题描述】:

我的 Web API 解决方案有 3 个项目:控制器层、业务层、数据访问层。 Unity 安装在控制器层项目中,用于实现 DI。业务和数据层中的每个类都有一个与之关联的接口。现在如何在符合 DI 标准的同时从 A 业务层访问 B 业务层中的功能? Unity 未安装在业务层项目中。 目前我正在做的是:

public class BBusiness
{
    IBDataAccess bDataAccess;
    IADataAccess aDataAccess;

    public BBusiness(IBDataAccess bDataAccessParam, IADataAccess 
    aDataAccessParam)
    {
        this.bDataAccess=bDataAccessParam;
        this.aDataAccess=aDataAccessParam;
    }
    public function()
    {
        ABusiness obj=new ABusiness(this.aDataAccess);
        obj.functionInABusiness();
    }
}

【问题讨论】:

标签: c# asp.net-web-api dependency-injection unity-container 3-tier


【解决方案1】:

据我所知(我对 DI 很陌生),您不应该在 BBusiness 内创建对象 ABusiness

你应该做的是类似的事情

public function()
{
    aDataAccess.functionInClassThatImplementsInterfaceIADataAccess();
}

您的解决方案意味着,BBusiness 仍然依赖于 ABusiness,您希望通过使用 DI 来避免这种情况。

【讨论】:

  • 您能详细说明一下吗?我不明白你的意思 aDataAccess.functionInClassThatImplementsInterfaceIADataAccess();
  • 你有你的接口 IADataAccess,并且在你的项目中的某个地方你有一个实现该接口的类,我假设。那么,您使用 DI 做什么:首先通过构造函数将接口注入到类 BBusiness。然后你可以调用该接口的方法:aDataAccess.functionOfTheInterface();例如。该功能必须在某个类中实现,发生的情况是,该代码在没有类 BBusiness 依赖于 ABusiness 的情况下执行。依赖注入意味着,一个类不会创建它需要的方法和函数的对象。
  • DI是什么的另一个答案,请看stackoverflow.com/questions/130794/…
  • 但我想访问 ABusiness 层内部的函数,而不是 ADataAccess 层。那么我可以在这里将 ABusiness (IABusiness) 的接口注入到构造函数中吗?喜欢.. public BBusiness(IBDataAccess bDataAccessParam, IABusiness aBusinessParam)
  • 如果接口 IABusiness 是由 ABusiness 类实现的,那么这应该可以工作,您可以通过执行 aBusinessParam.FunctionOfABusiness() 之类的操作来调用 ABusiness 的功能;
【解决方案2】:

这就是层的全部思想:你不能从 A 访问 B 中的函数。A 忙于自己的业务,甚至不知道 B 的存在。但是,B 知道 A ,了解 A 的事件(无论 A 提供什么类型的事件)并对它们做出反应。

【讨论】:

    【解决方案3】:

    因为ABusiness 是一个的服务,它通常会设置如下:

    public interface IABusiness
    {
        void functionInABusiness();
    }
    
    public class ABusiness : IABusiness
    {
        // making the variable private readonly ensures that nothing
        // can set it after the constructor does (thus it can never be null)
        private readonly IADataAccess aDataAccess;
    
        public ABusiness(IADataAccess aDataAccessParam)
        {
            // Guard clause ensures you cannot set this.aDataAccess to null
            if (aDataAccessParam == null)
                throw new ArgumentNullException(nameof(aDataAccessParam));
            this.aDataAccess=aDataAccessParam;
        }
    
        public void functionInABusiness()
        {
            // Do something with aDataAccess
        }
    }
    

    然后您将添加IABusiness 作为BBusiness 的依赖项。

    public interface IBBusiness
    {
        void function();
    }
    
    public class BBusiness : IBBusiness
    {
        private readonly IBDataAccess bDataAccess;
        private readonly IABusiness aBusiness;
    
        public BBusiness(IBDataAccess bDataAccessParam, IABusiness aBusinessParam)
        {
            if (bDataAccessParam == null)
                throw new ArgumentNullException(nameof(bDataAccessParam));
            if (aBusinessParam == null)
                throw new ArgumentNullException(nameof(aBusinessParam));
            this.bDataAccess=bDataAccessParam;
            this.aBusiness=aBusinessParam;
        }
        public function()
        {
            this.aBusiness.functionInABusiness();
            // Do something else...
        }
    }
    

    在您的 composition root 中,您将设置 Unity 以将 IABusinessABusinessIBBusinessBBusiness 关联。请注意,如果类和接口以某种方式命名或放在某个位置等,某些项目会使用自动执行此步骤的约定。

    container.RegisterType<IABusiness, ABusiness>();
    container.RegisterType<IBBusiness, BBusiness>();
    container.RegisterType<IADataAccess, ADataAccess>();
    container.RegisterType<IBDataAccess, BDataAccess>();
    

    整个想法是您不要直接从BBusiness 类引用ABusiness 类,因此您可以将IABusiness 的不同实例注入BBusiness(用于测试,或创建装饰器类IABusiness 周围增加了额外的责任,等等)

    此外,IABusiness 接口可能与ABusiness 位于不同的程序集中(例如),因此BBusiness 程序集不需要引用ABusiness 程序集。

    请注意,您没有关注 Microsoft 的 capitalization conventions,这可能会使关注您的人难以维护此代码。 .NET 中的方法名称应该是 Pascal 大小写,例如 FunctionInABusiness()

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多