具有单例的Structuremap泛型类型

时间:2013-11-20 19:52:18

标签: c# generics structuremap

我有一个问题,我想使用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>())
        ));

0 个答案:

没有答案