public interface IRepository<T> where T : Entity
{
void Delete(T entity);
T[] GetAll();
T GetById(int id);
void SaveOrUpdate(T enity);
void Merge(T entity);
}
public interface ITeamEmployeeRepository : IRepository<TeamEmployee>
{
PagedList<TeamEmployee> GetPagedTeamEmployees(int pageIndex, int pageSize);
}
public class Repository<T> : IRepository<T> where T : Entity
{
private readonly ISession _session;
protected Repository()
{
_session = GetSession();
}
public virtual void Delete(T entity)
{
_session.Delete(entity);
}
public virtual T[] GetAll()
{
return _session.CreateCriteria<T>().List<T>().ToArray();
}
public virtual T GetById(int id)
{
return _session.Get<T>(id);
}
public virtual void SaveOrUpdate(T enity)
{
_session.SaveOrUpdate(enity);
}
public void Merge(T entity)
{
_session.Merge(entity);
}
protected ISession GetSession()
{
return new SessionBuilder().GetSession();
}
}
public class TeamEmployeeRepository : Repository<TeamEmployee>, ITeamEmployeeRepository
{
public PagedList<TeamEmployee> GetPagedTeamEmployees(int pageIndex, int pageSize)
{
return GetSession().QueryOver<TeamEmployee>()
.Fetch(x => x.Employee).Eager
.Fetch(x => x.Team).Eager
.ToPagedList(pageIndex, pageSize);
}
}
现在我按如下方式注册存储库:
For<ILoanedItemRepository>().Use<LoanedItemRepository>();
For<ITeamEmployeeRepository>().Use<TeamEmployeeRepository>();
For<IArticleRepository>().Use<ArticleRepository>();
For<ISalesmanRepository>().Use<SalesmanRepository>();
For<ISalesmanArticleRepository>().Use<SalesmanArticleRepository>();
For<IGoodsGroupRepository>().Use<GoodsGroupRepository>();
For<IEmployeeRepository>().Use<EmployeeRepository>();
这非常麻烦,特别是如果有新的存储库。
更容易和更好的注册将是:
For(typeof(IRepository<>)).Use(typeof(Repository<>));
但这不起作用。 StructureMap每次都说我没有为PluginFamily Core.Domain.Bases.Repositories.ITeamEmployeeRepository定义默认实例。
我在stackoverflow上搜索并找到了新的东西:
Scan(x =>
{
x.AssemblyContainingType(typeof(TeamEmployeeRepository));
x.AddAllTypesOf(typeof (IRepository<>));
x.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});
但仍然是同样的错误信息。
如何使用StructureMap 2.6.1.0注册我的存储库?
答案 0 :(得分:9)
我找到了解决方案。
Scan(x =>
{
x.WithDefaultConventions();
x.AssemblyContainingType(typeof(TeamEmployeeRepository));
x.AddAllTypesOf(typeof(Repository<>));
x.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});
WithDefaultConventions 是显示代码的重要部分,因为使用此设置,您可以说StructureMap使用将ITeamEmployeeRepository映射到TeamEmployeeRepository的约定。因此,StructureMap假设该类被命名为没有前缀 I 的接口名称。
答案 1 :(得分:3)
我发现这个问题谷歌搜索“structuremap resolve generic”。现有的答案很好但很复杂。对于那些寻求简单答案的人:对于接口ISome和实现类我们写一些
c.For<ISome>().Use<Some>()
而对于通用的ISome&lt; T&gt;实现类Some&lt; T&gt;我们写
c.For(typeof(ISome<>)).Use(typeof(Some<>))
这就是全部
答案 2 :(得分:-1)
我最近通过进行小型重新设计解决了类似的问题,这使得一切变得更加简单。这对你也有用。您可以尝试从设计中删除特定接口,例如ITeamEmployeeRepository
和ILoanedItemRepository
。我这样做的方法是使用扩展方法。这是一个例子:
public static class RepositoryExtensions
{
public static TeamEmployee GetById(
this IRepository<TeamEmployee> repository, int id)
{
return repository.Single(e => e.TeamEmployeeId == id);
}
public static IQueryable<Salesman> GetActiveSalesmen(
this IRepository<ISalesmanRepository> repository)
{
return repository.Where(salesman => salesman.Active);
}
// etc
}
之后我创建了一个IRepositoryFactory
,允许我创建某种类型的存储库:
public interface IRepositoryFactory
{
IRepository<T> CreateNewRepository<T>();
}
当使用此接口时,很容易创建此工厂的实现,要求容器创建具体的Repository<T>
。 RepositoryFactory
可能如下所示:
public class RepositoryFactory : IRepositoryFactory
{
public IRepository<T> CreateNewRepository<T>()
{
return ObjectFactory.GetInstance(typeof(Repository<T>));
}
}
使用此设计,您只需通过其RepositoryFactory
界面注册具体IRepositoryFactory
即可完成。现在注入IRepository<ITeamEmployeeRepository>
并让客户端调用IRepositoryFactory
方法,而不是在旧设计中注入CreateNewRepository<T>
。由于使用了扩展方法,您可以在存储库中调用特定于类型的方法。
这样做的另一个好处是,您不需要在每次实现时重新实现最初在ITeamEmployeeRepository
上定义的方法。
这种设计在我的情况下非常有效,特别是因为我的IRepository<T>
接口使用了表达式树。当然,我不可能看到这样的设计是否适合你,但我希望它会。
答案 3 :(得分:-2)
您需要创建自己的ITypeScanner
并在Scan()
来电中注册。查看GenericConnectionScanner
的源代码作为起点。您不必搜索类型以查看它们是否实现IRepository<T>
,而是查看它们是否实现了实现IRepository<T>
的任何接口,然后注册该接口的类型。
更新:所有关于IRepository<T>
的讨论让我过度思考这个问题,当时它真的是一个无关紧要的细节。只需使用Rookian建议的DefaultConventions扫描程序。