在我的应用程序中,我希望在一个类中获取多个存储库的依赖项,其中并不是每次都需要它们。我在Windsor中使用Typed Factory facility,而不是在不必要的地方构造每个实例的实例。
但是,为每个存储库注册一个工厂有点麻烦,我想用一个开放的通用注册来代替它。我想做的事情如下所示:
container.Register(
Component.For<IFactory<IRepository<>>>().AsFactory()
);但是,这是一个语法错误,因为缺少IRepository的类型参数。有没有什么语法可以让我这样做呢?
注意:我知道我可以注册一个非类型化的Factory接口,并使用它来创建多个组件。我对此不感兴趣,因为这本质上是对服务定位器的依赖-如果我没有注册依赖,那么在代码尝试使用它之前,我不会知道它-使用我的方法,我在构造函数中知道这一点,即使我还没有创建实例。
完整(简化)示例如下:
public class TestA { }
public class TestB { }
public interface IRepository<T> { T Create(); }
public class Repository<T> : IRepository<T>
{
public T Create() { return Activator.CreateInstance<T>(); }
}
public interface IFactory<T>
{
T Create();
void Release(T instance);
}
class Program
{
static void Main(string[] args)
{
IWindsorContainer container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
// Individual registrations of repositories here are fine
Component.For<IRepository<TestA>>().ImplementedBy<Repository<TestA>>(),
Component.For<IRepository<TestB>>().ImplementedBy<Repository<TestB>>()
);
container.Register(
// Individual registrations of factories - works, but trying to avoid!
Component.For<IFactory<IRepository<TestA>>>().AsFactory(),
Component.For<IFactory<IRepository<TestB>>>().AsFactory()
);
container.Register(
// Generic Registration of Factories - syntax errors
// Component.For<IFactory<IRepository<>>>().AsFactory()
// Component.For(typeof(IFactory<IRepository<>>)).AsFactory()
);
var factoryA = container.Resolve<IFactory<IRepository<TestA>>>();
var factoryB = container.Resolve<IFactory<IRepository<TestB>>>();
var repoA = factoryA.Create();
var repoB = factoryB.Create();
Console.WriteLine("Everything worked");
}
}发布于 2012-10-15 09:33:02
你的工厂接口定义有点太“开放”了。更改工厂接口,如下所示:
public interface IRepositoryFactory<T>
{
IRepository<T> Create();
void Release(IRepository<T> instance);
}然后你可以注册:
container.Register(Component.For(typeof(IRepositoryFactory<>)).AsFactory());并解决:
var factoryA = container.Resolve<IRepositoryFactory<TestA>>();
var factoryB = container.Resolve<IRepositoryFactory<TestB>>();发布于 2012-10-14 21:43:21
有一种将存储库分组在一起的模式。它被称为unit of work。因此,创建一个引用这些存储库的工作类单元,而不是创建一个工厂来创建存储库。例如:
public abstract class UnitOfWork : IDisposable
{
// here is your factory
protected abstract IRepository<T> GetRepository<T>();
public IRepository<User> Users
{
get { return this.GetRepository<User>();
}
public IRepository<Customer> Customers
{
get { return this.GetRepository<Customer>();
}
// etc..
}在您的Composition Root中,您可以定义一个包含对Windsor的引用的UnitOfWork实现,并使您能够获得IRepository<T>实现:
internal sealed class WindsorUnitOfWork : UnitOfWork
{
private WindsorContainer container;
public WindsorUnitOfWork(WindsorContainer container)
{
this.container = container;
}
protected override IRepository<T> GetRepository<T>()
{
return this.container.Resolve<IRepository<T>>();
}
}并按如下方式进行注册:
container.Register(Component.For<UnitOfWork>()
.ImplementedBy<WindsorUnitOfWork>()
.LifeStyle.Transient);消费者现在有了一种非常方便的方式来使用存储库:
private readonly UnitOfWork db;
public KarmaService(UnitOfWork db)
{
this.db = db;
}
public int CalculateKarmaForActiveUsersByName(string name)
{
var users =
from user in this.db.Users
where user.Name == name
where user.Active
select user;
return users.Sum(user => user.Karma);
}https://stackoverflow.com/questions/12881772
复制相似问题