C# 简单注入器-批量/自动注册新类
在简单喷油器中,自动注册这些类别是否困难:C# 简单注入器-批量/自动注册新类,c#,dependency-injection,simple-injector,C#,Dependency Injection,Simple Injector,在简单喷油器中,自动注册这些类别是否困难: public class RepositoryA : Repository<Hammers>, IRepositoryA { ... implementing code here ... } public interface IRepositoryA: IRepository<Hammers> { //no methods } public class RepositoryB : Repository<Kni
public class RepositoryA : Repository<Hammers>, IRepositoryA
{
... implementing code here ...
}
public interface IRepositoryA: IRepository<Hammers>
{ //no methods
}
public class RepositoryB : Repository<Knives>, IRepositoryB
{
... implementing code here ...
}
public interface IRepositoryB: IRepository<Knives>
{ //no methods
}
public class RepositoryC : Repository<Swords>, IRepositoryC
{
... implementing code here ...
}
public interface IRepositoryC: IRepository<Swords>
{ //no methods
}
Simple Injector支持的用例是通过相关的通用接口批量注册一组实现。换句话说,通过这样做:
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
typeof(StateRepository).Assembly);
但是,一定要确保您理解在存储库上实现自定义接口违反了SOLID原则。防止这种违反是有益的。请查看以获取有关此的更多信息 我更关心设计,而不仅仅是让它发挥作用。你认为我应该不再需要一个IRepository,而只需要通过IRepository吗?因此,我应该改为“StateRepository:IRepository,IStateRepositor”,而不是“StateRepository:IRepository”,顺便说一句,我想我是在遵循存储库模式的实现方式。你认为存储库模式违反了SOLID原则吗?@sksallaj:正如Martin Fowler在他的书中描述的存储库模式(他使用Creatia和一个
匹配方法),存储库没有违反SOLID,但它的使用是有限的,因为他使用Creatia。当您开始从存储库中公开IQueryable
时,您将违反LSP,当您开始向特定存储库实现添加额外的查询方法时(正如Eric Evens在DDD中所建议的),您将违反SRP、OCP和ISP。请注意,在进行DDD时,这可能是有意义的,但您必须清楚地权衡利弊。这篇文章确实是我的。Martin Fowler描述的存储库模式包含一个匹配(条件)
方法,在该方法中,这些条件可以与其他条件组合以构建查询。此标准是规范模式的一个示例。您可以将此“查询/处理程序模式”(我称之为)视为查询对象,但没有条件。它是基于消息的编程/体系结构更大概念的一部分。我仍然在我的应用程序中使用存储库模式(尽管在我的上一个应用程序中,存储库只是一般GetByIdQuery查询之上的一个门面)。这些查询对象显式地不包含任何条件。这使业务/数据层能够完全控制生成的查询,并允许通过连接序列化这些查询。让使用者创建标准将业务逻辑移动到表示层,这在IMO中是不好的。
var repositoryAssembly = typeof(StateRepository).Assembly;
var registrations =
from type in repositoryAssembly.GetExportedTypes()
where type.Namespace == "MappingTool.Repository"
where type.GetInterfaces().Any()
where !type.IsAbstract
select new
{
Service = type.GetInterfaces().Single(),
Implementation = type
};
foreach (var reg in registrations)
{
container.Register(reg.Service, reg.Implementation, Lifestyle.Transient);
}
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
typeof(StateRepository).Assembly);
container.Register<IRepository<A>, RepositoryA>();
container.Register<IRepository<B>, RepositoryB>();
container.Register<IRepository<C>, RepositoryC>();
/* add more here */
var repositoryTypes = OpenGenericBatchRegistrationExtensions.GetTypesToRegister(
container, typeof(IRepository<>), repositoryAssembly);
foreach (Type implementationType in repositoryTypes)
{
Type serviceType =
implementationType.GetInterfaces().Where(i => !i.IsGenericType).Single();
container.Register(serviceType, implementationType, Lifestyle.Transient);
}