所以我有这个应用程序,我使用IOC(autofac)。与此同时,我发现自己处于需要工厂的位置。在工厂内部,我创建了具有依赖关系的新对象 - 所以现在我想知道,我怎么能嫁给这些?
public class SubscriptionHandlerFactory : ISubscriptionHandlerFactory
{
public ISubscriptionHandler GetProvider(StreamType streamType)
{
switch (streamType)
{
case StreamType.Rss:
return new RssSubscriptionHandler(null,null,null,null);
case StreamType.Person:
return new PersonSubscriptionHandler(null, null, null, null);
default:
throw new ArgumentOutOfRangeException(nameof(streamType), streamType, null);
}
}
}
答案 0 :(得分:1)
您可以使用named and keyed service并使用IIndex<TKey, TService>
注册可能如下所示:
builder.RegisterType<RssHandler>().Keyed<ISubscriptionHandler>(StreamType.Rss);
builder.RegisterType<PersonHandler>().Keyed<ISubscriptionHandler>(StreamType.Person);
builder.RegisterType<SubscriptionHandlerFactory>().As<ISubscriptionHandlerFactory>();
和像这样的工厂:
public class SubscriptionHandlerFactory : ISubscriptionHandlerFactory
{
public SubscriptionHandlerFactory(IIndex<StreamType, ISubscriptionHandler> handlers)
{
this._handlers = handlers;
}
private readonly IIndex<StreamType, ISubscriptionHandler> _handlers;
public ISubscriptionHandler GetProvider(StreamType streamType)
{
return this._handlers[streamType];
}
}
答案 1 :(得分:0)
您无法使用IoC永远抽象出对象的实例化。在某些时候,您将不得不创建一个具体的实例(在工厂内或您的IoC容器中)
您可以将autofac容器注入工厂,或者由于工厂本身实现了接口,因此您可以将工厂的不同版本注入到类可能需要的工厂中(例如,如果您需要不同的工厂进行单元测试) )
答案 2 :(得分:0)
我解决了。的种类。因为我不想依赖Autofac它自己被撕裂了。但是感谢@ martin-costello我觉得我可能不需要使用autofac,但是IDependencyResolver的构建不那么邪恶。由于我无法将autofac注册为IDependencyResolver,因此我将DependencyResolver注册为IDependencyResolver。再迈近一步。由于注册发生在autofac DependencyResolver.SetResolver发生之前,我需要使用Lazy,这最终解决了我的问题。
此处的代码(或至少是我发现的最佳解决方案)
// other registration
builder.RegisterType<RssSubscriptionHandler>();
builder.RegisterType<PersonSubscriptionHandler>();
// even more registration here
builder.RegisterType<SubscriptionHandlerFactory>()
.As<ISubscriptionHandlerFactory>()
.WithParameter(new TypedParameter(typeof(Lazy<IDependencyResolver>),
new Lazy<IDependencyResolver>(() => DependencyResolver.Current)));
然后工厂更改为此(清理前):
public class SubscriptionHandlerFactory : ISubscriptionHandlerFactory
{
private readonly Lazy<IDependencyResolver> resolver;
public SubscriptionHandlerFactory(Lazy<IDependencyResolver> resolver)
{
this.resolver = resolver;
}
public ISubscriptionHandler GetProvider(StreamType streamType)
{
switch (streamType)
{
case StreamType.Rss:
return (ISubscriptionHandler)this.resolver.Value.GetService(typeof(RssSubscriptionHandler));
case StreamType.Person:
return (ISubscriptionHandler)this.resolver.Value.GetService(typeof(PersonSubscriptionHandler));
default:
throw new ArgumentOutOfRangeException(nameof(streamType), streamType, null);
}
}
}
现在这是最好/干净/不那么邪恶/不那么具体/抽象/无论我能解决什么解决方案。欢迎任何评论。