我正在开发一个WinForm应用程序,我正在使用Repository Pattern,我使用Servicestack OrmLite进行数据访问,使用Simple Injector进行IoC。
在我的program.cs中,我有2个注册2个不同的OrmLiteConnectionFactory
,但目前我无法注册,因为我无法注册命名...使用FunQ我可以用
container.Register<IDbConnectionFactory>("db1", _ => new OrmLiteConnectionFactory(
ConfigurationManager.ConnectionStrings["db1"].ConnectionString,
SqlServerDialect.Provider));
container.Register<IDbConnectionFactory>("db2", _ => new OrmLiteConnectionFactory(
ConfigurationManager.ConnectionStrings["db2"].ConnectionString,
SqlServerDialect.Provider));
这是我的program.cs Bootstrap方法
private static void Bootstrap()
{
// Create the container as usual.
Container = new Container();
string conn1 = ConfigurationManager.ConnectionStrings["dbconn1"].ConnectionString;
string conn2 = ConfigurationManager.ConnectionStrings["dbconn2"].ConnectionString;
OrmLiteConnectionFactory connectionFactory = new OrmLiteConnectionFactory(conn1,
ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance);
Container.RegisterSingle<OrmLiteConnectionFactory>(connectionFactory1);
OrmLiteConnectionFactory connectionFactory2 = new OrmLiteConnectionFactory(conn2,
ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance);
// how do I register this one without a name?
Container.RegisterSingle<OrmLiteConnectionFactory>(connectionFactory2);
Container.Register<MainForm>();
}
提前致谢
答案 0 :(得分:16)
由于您有两个不同的数据库,每个数据库都有不同的架构,因此不同的OrmLiteConnectionFactory
不可互换。这意味着如果您更换它们,您的系统将停止工作。这表明你打破了Liskov Substitution Principle。因此,在这种情况下的一般解决方案是为每个工厂提供自己的接口,并让每个存储库依赖于该特定接口。这允许您唯一地注册它们,让容器毫无疑问地解析对象图。
如果给每个工厂自己的抽象不是一个选项,或者方便,另一个选择是注册您的存储库而不需要自动连接。通过向委托人注册您的存储库,您可以完全控制注入存储库的内容。例如:
container.Register<IOrderRepository>(() => new SqlOrderRepo(connectionFactory1));
container.Register<IUserRepository>(() => new SqlUserRepo(
connectionFactory2,
container.GetInstance<ILogger>()));
第三种选择是使用context based injection,如果您执行以下操作:
var f1 = Lifestyle.Singleton.CreateRegistration<IDbConnectionFactory>(
() => new OrmLiteConnectionFactory(
conn1,
ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance),
container);
var f2 = Lifestyle.Singleton.CreateRegistration<IDbConnectionFactory>(
() => new OrmLiteConnectionFactory(
conn2,
ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance),
container);
container.RegisterConditional(typeof(IDbConnectionFactory), f1, InjectedInto<SqlOrderRepo>);
container.RegisterConditional(typeof(IDbConnectionFactory), f2, InjectedInto<SqlUserRepo>);
// Helper method.
static bool InjectedInto<T>(PredicateContext c) =>
c.Consumer.ImplementationType == typeof(T);
开箱即用Simple Injector不支持注册键控注册,但有几种方法可以按照此page的说明执行此操作。该页面还解释了为什么没有内置支持。这是一个深思熟虑的设计决定。