【问题标题】:injecting the correct type to my business class using Autofac使用 Autofac 为我的业务类注入正确的类型
【发布时间】:2015-09-30 09:51:41
【问题描述】:

我目前有一个业务类,其构造函数采用存储库实现。此存储库有多种实现。在运行时,我想决定应该提供哪个存储库实现。我是使用 DI 框架和 Autofac 的新手。这是我的存储库实现。

public interface IRepository
{
  string GetData();
}

public class ServiceRepository : IRepository
{
  ///implementation..
}

public class DatabaseRepository : IRepository
{
  ///implementation..
}



public class BusinessClass
{
   public BusinessClass(IRepository repo)
   {
     //assign to local variable
   }
}

如您所见,IRepository 有多个实现。但是,我想在运行时决定应该将哪一个传递给我的商务舱。我浏览了这些示例herehere,但它们似乎没有解释如何实现这一要求。在这一点上,改变界面设计不是一种选择。我还需要实现一个工厂类来选择性地解析正确的类型吗?

【问题讨论】:

  • 您在应用程序启动时根据配置文件或任何插件系统(如果有的话)注册您想要的实现。如果你需要“即时”改变东西(IMO 有点臭),那么你需要一个工厂。
  • 为什么会有点臭?与您所说的不矛盾,而只是试图理解原因。此业务类依赖于数据的外部服务。前端会根据用户的选择向它发送数据源。有时它可能是 webservice-A。有时它可能是 webservice-B,有时它可能是数据库。为这些选择中的每一个复制业务类,以便 Autofac 只有一个类要解决,似乎我们正在润湿现有代码的 DRYness 以适应 DI 框架。不用说,这些服务是我无法控制的。
  • 那么你的业务服务应该以工厂为依赖,该工厂将由autofac注入。

标签: oop dependency-injection autofac ooad


【解决方案1】:

有几种比使用工厂更简洁的方法。

  • 您可以使用责任链模式,使用 Autofac 解析所有 IRepositories,然后每个存储库可以告诉您他们是否负责处理该请求。
  • 您可以直接打开它并说,我有一个存储库列表,我需要一个服务来获取这些存储库并根据一组业务规则(本质上是一个工厂)返回一个特定的存储库。虽然这种方法使解决方案有点单元测试友好。

只是一些选项供您考虑:)

【讨论】:

    【解决方案2】:

    你可以在这里使用工厂模式,但你不需要创建一个专门的工厂类,Func 就足够了。你的业务层不应该知道这个切换逻辑,它应该去应用层控制器。

    一个可能的例子:

    你的控制器

    public void SomeController(Func<string, IBusinessService> serviceFactory)
    {
        this.serviceFactory = serviceFactory;
    }
    ...
    //somewhere inside controller
    serviceFactory("database").SomeBusinessLogic();
    ...
    

    和 Autofac 注册:

    builder
    .RegisterType<ServiceRepository>()
    .Named<IRepository("service");
    
    builder
    .RegisterType<DatabaseRepository>()
    .Named<IRepository>("database");
    
    builder
    .Register<Func<string,IBusinessService>>(cx =>
    {
        var componentContext = cx.Resolve<IComponentContext>();
        return (key =>
            new BusinessService(componentContex.ResolveNamed<IRepository>(key))
        );
    }
    )
    .As<Func<string, IBusinessService>>();
    

    【讨论】:

      猜你喜欢
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-04
      相关资源
      最近更新 更多