使用Autofac将正确的类型注入我的业务类

时间:2015-07-11 19:56:17

标签: oop dependency-injection autofac ooad

我目前有一个业务类,其构造函数接受存储库实现。此存储库有多个实现。在运行时,我想决定应该提供哪个存储库实现。我是新手使用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,但他们似乎没有解释如何达到这个要求。此时无法更改界面设计。我是否仍需要实现工厂类来有选择地解析正确的类型?

2 个答案:

答案 0 :(得分:0)

有几种更简洁的方法,而不是使用工厂。

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

您可以考虑以下几种选择:)

答案 1 :(得分:0)

您可以在此处使用Factory模式,但您不需要创建专用工厂类,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>>();