crb*_*04c 6 c# factory dependency-injection
使用DI方法处理条件子工厂的正确方法是什么?场景是注入到条目中的加载器对象取决于该条目的设置.最初我是将IoC容器注入工厂并使用它来根据命名约定来解决.但是,我真的想保持工厂清洁容器.
将工厂注入到将从数据库加载所有设置的类中,然后使用工厂创建一组条目.这些设置确定将在给定条目内使用哪个加载器.
编辑:更改代码以更好地突出显示实际问题.问题是必须同时支持多个数据库管理器,如果不是这样,那么它将很简单.数据库管理器类型由为特定条目存储的条目设置确定.
public class Entry : IEntry
{
private ISomething loader;
public Entry(ISomething something)
{
this.loader = something;
}
}
public class EntryFactory : IEntryFactory
{
IEntry BuildEntry(IEntrySetting setting)
{
//Use setting object to determine which database manager will be used
}
}
public class EntryManager
{
public EntryManager(IEntryFactory entryFactory)
{
var entrySettings = this.settings.Load();
foreach(var setting in entrySettings)
{
this.entries.Add(entryFactory.BuildEntry(setting));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我曾考虑让子工厂在主要工厂注册并以这种方式解决,但我不知道是否有更好的方法.
这取决于你的 DI 框架允许什么,而你没有指定它。使用Autofac基于委托的注册,我得到了以下解决方案。请注意,在这两种情况下,ILoaderFactory和IEntryFactory都已被简单工厂替换。Func<>
解决方案1,使用两个工厂:
public class EntryManager
{
public EntryManager(Func<ILoader, IEntry> entryFactory, Func<Settings, ILoader> loaderFactory)
{
var entrySettings = this.settings.Load();
foreach(var setting in entrySettings)
{
this.entries.Add(entryFactory(loaderFactory(setting)));
}
}
}
private static ILoader SelectLoader(IEntrySetting settings)
{
// your custom loader selection logic
}
var builder = new ContainerBuilder();
builder.RegisterType<EntryManager>();
builder.RegisterType<Entry>().As<IEntry>();
builder.Register((c, p) => SelectLoader(p.TypedAs<IEntrySetting>()));
IContainer container = builder.Build();
container.Resolve<EntryManager>();
Run Code Online (Sandbox Code Playgroud)
解决方案2,仅使用一个工厂:
public class EntryManager
{
public EntryManager(Func<IEntrySetting, IEntry> entryFactory)
{
var entrySettings = this.settings.Load();
foreach(var setting in entrySettings)
{
this.entries.Add(entryFactory(setting));
}
}
}
private static ILoader SelectLoader(IEntrySetting settings)
{
// your custom loader selection logic
}
var builder = new ContainerBuilder();
builder.RegisterType<EntryManager>();
builder.Register((c, p) => new Entry(SelectLoader(p.TypedAs<IEntrySetting>()))).As<IEntry>();
IContainer container = builder.Build();
container.Resolve<EntryManager>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2762 次 |
| 最近记录: |