使用继承模板化的服务依赖项注入

时间:2018-04-06 04:08:48

标签: c# design-patterns software-design

使用模板模式(继承)为类注入依赖项有什么优缺点。

假设我正在创建一堆业务服务类,例如,ISecurityService实现为SecurityService。

而且,如果我知道所有业务服务(包括ISecurityService)将/应该依赖于IBusinessContext来获取服务上下文信息,我可以使用模板模式(使用继承)来实现/强制执行吗?

方法#1:

public interface IBusinessContext
{
   public int Property { get; }
}

public interface IService
{
   public IBusinessContext Context { get; }
}

public abstract class ServiceBase : IService
{
   public IBusinessContext Context { get; }

   public ServiceBase(IBusinessContext context) { _context = context; }
}

public interface IBusinessServiceN : IService
{
   public void DoSomething();
}

public class BusinessServiceN : ServiceBase, IBusinessServiceN
{
   public SecurityService(IBusinessCnotext context)
          : base(context) { }

   public void DoSomething() { }
}

方法#2:

public interface IBusinessContext
{
   public int Property { get; }
}

public interface IBusinessServiceN
{
   public void DoSomething();
}

public class BusinessServiceN : IBusinessServiceN
{
   private IBusinessContext _context;

   public SecurityService(IBusinessCnotext context) { _context = context; }

   public void DoSomething() { }
}

哪种方法更受欢迎?为什么?

2 个答案:

答案 0 :(得分:0)

数字2,因为为什么服务将IBusinessContext公开为公共财产是有意义的?它没有。这是它的一个依赖项,它不需要通过接口或甚至具体类来公开。

消费IService的合同不是/不应包括创建具体类来履行IService的合同。如果我可以在没有IService实例的情况下实现IBusinessContext这是一件好事,特别是在编写单元测试和模拟IService时。或者,如果我的IService实现需要ICompleteContext而不是包含IBusinessContext,那么应该不会像在#1中那样人为地使用某些界面进行约束。

答案 1 :(得分:0)

这一切都取决于您的要求。除非您的抽象类中有可重用的代码,否则方法#1不会增加任何好处。

当您拥有一个共同的工作流程并且您确定此工作流程不会更改时,模板方法模式真的很闪亮;虽然子实现可能会更改某些步骤,但它们可能不会更改工作流程结构。

假设您的DoSomething方法中有一个“严格”的工作流程,并且有一些常用的继承类的步骤:

public virtual void DoSomething() {
        DoSomethingFirst(); // -> common to all classes
        DoSomethingAfter(); //-> each class has unique implementation
}

您的基类可以采用以下形式:

 public abstract class ServiceBase : IService
{
    public IBusinessContext Context { get; }

    public ServiceBase(IBusinessContext context) { Context = context; }

    public void DoSomethingFirst() {
        // common implementation here
    }

    public abstract void DoSomethingAfter();

    public virtual void DoSomething() {
        DoSomethingFirst(); 
        DoSomethingAfter();
    }
}

你的具体课程:

 public class BusinessServiceN : ServiceBase, IBusinessServiceN
{
    public BusinessServiceN(IBusinessContext context)
           : base(context) { }

    public override void DoSomethingAfter()
    {
        //Your custom implementation here
    }
}

如您所见,您的DoSomething()方法和共享/可重复使用的DoSomethingFirst()方法具有强制结构。