我有一个问题,我想使用StructureMap来创建单例,但是StructureMap创建了多个实例。在尝试阅读有关如何正确处理泛型的StructureMap文档时,我感到困惑。
我必须为给定实体实例化一个存储库,同时为由于泛型而需要实体类型的数据连接提供实例。
这是我的VendorRepository代码,许多其他存储库的结构完全相同。 IVendorRepository需要使用Vendor类型注入IRepository。而且我不太确定如何以单身方式实现这一目标。
public interface IVendorRepository {
...
}
public class VendorRepository : IVendorRepository {
private readonly IRepository<Vendor> _repository;
public VendorRepository(IRepository<Vendor> repository)
{
_repository = repository;
}
...
}
public class Vendor : DomainEntity
{
...
}
public class DomainEntity : IDomainEntity
{
...
}
这是数据连接部分。 SqlRepository通过currentSession处理实际连接。据我所知,每个DomainEntity存储库(例如VendorRepository)都需要它自己的SqlRepository实例。
public class SqlRepository<T> : IRepository<T> where T : class, IDomainEntity
{
private readonly ISession _currentSession;
public SqlRepository(ISession currentSession)
{
_currentSession = currentSession;
}
...
}
public interface IRepository<T> where T : IDomainEntity
{
...
}
最后,今天所有东西都被连线了。使用此代码,每次注入VendorRepository时,都会创建一个新实例。
For(typeof(IRepository<>)).Use(typeof(SqlRepository<>));
For<ISessionSource>()
.Use(context => ConfigurationSettings.RunAgainstLocalDatabase
? (ISessionSource) context.GetInstance<LocalSessionSource>()
: (ISessionSource) context.GetInstance<LiveSessionSource>());
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Use(context => context.GetInstance<ISessionSource>().OpenSession());
当我试图在这里使用单例时,我的currentSession被NHibernate关闭了。
For(typeof(IRepository<>)).Singleton().Use(typeof(SqlRepository<>));
修改 我不完全确定这是否会起作用,因为我有大量的存储库和实体。但我现在正试图手动添加这些以测试并查看它是否可行。我的最终目标是拥有所有实体存储库的单例(例如VendorRepository)。
For<IRepository<Vendor>>()
.HybridHttpOrThreadLocalScoped()
.Use(context => new SqlRepository<Vendor>(
context.GetInstance<ISessionSource>().OpenSession()
));
再次修改 这似乎更准确..虽然我还不太确定。
For<IVendorRepository>()
.HybridHttpOrThreadLocalScoped()
.Use(context => new VendorRepository(new SqlRepository<Vendor>(context.GetInstance<ISessionSource>().OpenSession())));
最终编辑: 以下是每个存储库需要发生的事情。我不知道如何在不列出每个存储库的情况下如何做到这一点(~100)。但是,在有限的测试中,使用单例而不是每个依赖注入的新实例都没有感觉到的性能提升。除非有一种更简单的方法让StructureMap选择存储库并自动正确地绑定它们,否则我将保留它创建多个实例的方式,而不是尝试列出以下代码的~100个几乎相同的副本。
For<IVendorRepository>()
.HybridHttpOrThreadLocalScoped()
.Singleton()
.Use(context => new VendorRepository(
new SqlRepository<Vendor>(context.GetInstance<ISession>())
));