我有一个典型的存储库接口IRepository<T>
和许多具体的存储库。大多数具体的存储库看起来像这样:
class ConcreteRepository<T> : IRepository<T> { .. }
这些很容易注册到StructureMap:
For(typeof(IRepository<>)).Use(typeof(ConcreteRepository<>));
但是,我选择的几个具体的存储库看起来像这样:
class AbnormalRepository<T1, T2> : IRepository<T1>, IAbnormal<T2> { .. }
我仍然希望将这些异常存储库用作IRepository<T>
s,因此对于这些我目前正在使用特殊规则:
// this sucks!
For(typeof(IRepository<Foo1>)).Use(typeof(AbnormalRepository<Foo1, Bar1>));
For(typeof(IRepository<Foo2>)).Use(typeof(AbnormalRepository<Foo2, Bar2>));
如果我能指定一个StructureMap可用于构建我的存储库的函数,那将是很好的,因为我知道我的所有异常存储库都实现了IAbnormal<T>
。有什么想法吗?
答案 0 :(得分:2)
创建自定义IRegistrationConvention并从容器配置的Scan()方法中调用它。
您可以在另一个stackoverflow问题上看到这个讨论的示例:
StructureMap IRegistrationConvention to register non default naming convention?
您还可以在StructureMap源代码本身中看到许多IRegistrationConvention示例。
答案 1 :(得分:1)
我没有一直关注你的用例,但是你可以使用一个函数(实际上是lambda)来构造你的对象。使用两个重载中的任何一个:
// lambda with no params
For<IRepository<Foo1>>().Use(() => { ... });
// context is a StructureMap SessionContext
For<IRepository<Foo1>>().Use(context => { ... });
要查看SessionContext之外的内容,请查看http://structuremap.github.com/structuremap/UsingSessionContext.htm
<强>增加:强>
using System;
using NUnit.Framework;
using StructureMap;
namespace SMTest2
{
public interface IRepository<T> {}
public class AbnormalRepository<T,T2> : IRepository<T>{ }
[TestFixture]
public class TestOpenGeneric
{
private IContainer _container ;
[SetUp]
public void DescribeContainer()
{
_container = new Container(cfg =>
cfg.For(typeof (IRepository<>)).Use(ctx => new AbnormalRepository<String, int>()));
}
[Test]
public void TestItWorks()
{
var stringVector = _container.GetInstance(typeof (IRepository<>));
Assert.IsInstanceOf<AbnormalRepository<String,int>>(stringVector);
}
}
}