Mic*_*ins 22 c# structuremap asp.net generics
我有一个接口(IRepository<T>
),目前正在为每个特定的存储库进行扩展,即:IUserRepository : IRepository<User>
.
这些接口中的每一个都具有相应的具体类,即:UserRepository : Repository<User>, IUserRepository
.
这些单独的存储库不添加任何其他功能,它们都是空接口/类,仅用于传递泛型.
我用StructureMap解决IUserRepository
到UserRepository
使用注册表与组装扫描仪和一些命名约定.
我希望这可以转向一种更优化的状态,而不是传递实例IUserRepository
并将其解析UserRepository
,我可以传递IRepository<User>
并解决它Repository<User>
.
这将消除创建这些额外的空接口和类的需要.
我无法找到一种方法来使用StructureMap的配置来设置这种通用映射.像这样的东西:
For(typeof(IRepository<>).Use(typeof(Repository<>)).WithTheGenericTypeFromTheInterfaceSuppliedAsATypeParameter();
Run Code Online (Sandbox Code Playgroud)
编辑
得到前几个答案之后,我想再澄清一下这个问题.
我不想为For
配置的位创建单独的类.我希望在我的代码中有以下类/接口:
IRepository<T> where T : Entity
Repository<T> : IRepository<T> where T : Entity
Person : Entity
Product : Entity
Order : Entity
Whatever : Entity
并按照惯例实现以下映射:
IRepository<Person> => Repository<Person>
IRepository<Product> => Repository<Product>
IRepository<Order> => Repository<Order>
IRepository<Whatever> => Repository<Whatever>
Run Code Online (Sandbox Code Playgroud)
但我不想为每个人创建一个映射,ala:
For<IRepository<Person>>().Use<Repository<Person>>();
For<IRepository<Product>>().Use<Repository<Product>>();
For<IRepository<Order>>().Use<Repository<Order>>();
For<IRepository<Whatever>>().Use<Repository<Whatever>>();
Run Code Online (Sandbox Code Playgroud)
我想要一个适用于任何IRepository的映射:
For<IRepository<>>().Use<Repository<>>().WithTheSameGenericType();
Run Code Online (Sandbox Code Playgroud)
然后我会使用它将存储库注入服务:
public MyService(IRepository<User> userRepository)
Run Code Online (Sandbox Code Playgroud)
并期望Repository<User>
在运行时解决.
Mic*_*ins 25
原来没有花哨的方法来调用,或者没有花哨的布线,你只需使用For
和Use
(非通用版本):
public class DataRegistry : Registry
{
public DataRegistry()
{
For(typeof (IRepository<>)).Use(typeof(Repository<>));
}
}
Run Code Online (Sandbox Code Playgroud)
当我注入IRepository<Person>
它时,它正在被解决为Repository<Person>
现在.
我遇到错误104,说Repository不能插入IRepository.这是因为存储库已被标记abstract
.使它成为非抽象的,修复了错误并且它正在按预期工作.
我建议你看看这个AddAllTypesOf
方法.我有一些类似的代码,并通过使用它来实现我的目标(并保持自动注册功能工作).
在你的情况下,你应该改变
For<IRepository<Person>>().Use<Repository<Person>>();
For<IRepository<Product>>().Use<Repository<Product>>();
For<IRepository<Order>>().Use<Repository<Order>>();
For<IRepository<Whatever>>().Use<Repository<Whatever>>();
Run Code Online (Sandbox Code Playgroud)
至
AddAllTypesOf(typeof(IRepository<>));
Run Code Online (Sandbox Code Playgroud)
最后,您的容器将类似于:
return new Container(x =>
{
x.Scan(y =>
{
y.TheCallingAssembly();
y.AddAllTypesOf(typeof(IRepository<>));
y.WithDefaultConventions();
});
});
Run Code Online (Sandbox Code Playgroud)