C# 使用Autofac创建可以返回不同SQL引擎的工厂
我正在尝试重构一个现有的解决方案,它不是为了使用DI和Autofac而编写的,并且遇到了一些问题。该解决方案支持多种SQL数据库类型MSSQL、MySQL、PostgreSQL等,用户可以在应用ie中连接多种不同类型的数据库。它们可能同时连接MSSQL和PostgreSQL数据库。当DB连接到应用程序时,类型存储在枚举中。在有问题的DBs上执行操作时,它当前使用以下静态工厂返回数据层:C# 使用Autofac创建可以返回不同SQL引擎的工厂,c#,dependency-injection,autofac,C#,Dependency Injection,Autofac,我正在尝试重构一个现有的解决方案,它不是为了使用DI和Autofac而编写的,并且遇到了一些问题。该解决方案支持多种SQL数据库类型MSSQL、MySQL、PostgreSQL等,用户可以在应用ie中连接多种不同类型的数据库。它们可能同时连接MSSQL和PostgreSQL数据库。当DB连接到应用程序时,类型存储在枚举中。在有问题的DBs上执行操作时,它当前使用以下静态工厂返回数据层: public static class DatabaseFactoryController { pub
public static class DatabaseFactoryController
{
public static IDatalayer GetDatalayer(ConnType databaseType)
{
switch (databaseType)
{
case ConnType.Mssql:
return new MssqlModel());
case ConnType.Postgre:
return new PostgreModel());
case ConnType.MySql:
return new MysqlModel());
default:
throw new ArgumentOutOfRangeException(nameof(databaseType));
}
}
}
现在的问题是代码中的其他控制器需要为用户当前访问的DB注入适当的数据层,例如:
public class SizeController : IDataController
{
private readonly IDatalayer _datalayer;
public SizeController(IDatalayer datalayer)
{
_datalayer = datalayer;
}
public Response<SizeInfo> GetData(IRequest request)
{
<actions taken here using datalayer>
}
}
但是,我如何连接Autofac以在控制器中动态注入正确的数据层,对于为控制器的任何给定调用实例化选择的DB,而无需转到ServiceLocator。我很确定这是可能的,但我对Autofac还很陌生,所以也许这就是为什么我不能根据文档使它工作的原因。我试过这样做:
但在该实现中,我看不到如何在运行时选择要注入构造函数的实现。也许我遗漏了一些非常明显的东西,或者我需要从根本上重构代码。任何输入都将被重视,因为我已经在这个问题上纠缠了一段时间。正如您使用的文章所示
public class SizeController : IDataController
{
private readonly IDatalayer _datalayer;
public SizeController(Func<ConnType, IDatalayer> dataLayerFactory)
{
_datalayer = dataLayerFactory(ConnType.Mssql);
}
public Response<SizeInfo> GetData(IRequest request)
{
//<actions taken here using datalayer>
_datalayer.SomeIDatalayerMethod();
}
}
在这种情况下,他们可能同时连接了MSSQL和PostgreSQL数据库,应该选择哪个IDatalayer?MS one还是Postgres one?有请求类型的那个,但我想我现在看到了下面给出的Aleksey的答案。我必须在运行时将ConnType作为参数传入,然后它才能选择正确的实现。谢谢。最后我做了类似的事情,除了存储Func并将ConnType作为GetData方法的参数,以确保每次调用都获得了正确的数据层。
public class SizeController : IDataController
{
private readonly IDatalayer _datalayer;
public SizeController(Func<ConnType, IDatalayer> dataLayerFactory)
{
_datalayer = dataLayerFactory(ConnType.Mssql);
}
public Response<SizeInfo> GetData(IRequest request)
{
//<actions taken here using datalayer>
_datalayer.SomeIDatalayerMethod();
}
}