给出以下代码来解析IProcessor
如何让autofac解析并为我的服务使用者创建这些?
我需要autofac来使用这个函数,或者类似于这个函数的东西来为相应的项创建相关的策略。需要以正确解析其依赖关系的方式创建这些策略。
理想情况下,这需要在应用程序的COMPOSITION ROOT
中进行。
下面的代码没有正确使用容器来构建实例。实际代码中的StrategyA
和StrategyB
将具有自己的依赖关系。当消费者处置时,他们也需要处理。
容器
我试过这个,并得到一个错误,说已经发生了解析操作。
var builder = new Autofac.ContainerBuilder();
builder.RegisterType<StrategyA>().As<IProcessor>().Keyed<IProcessor>(typeof(ItemA).Name).InstancePerDependency();
builder.RegisterType<StrategyB>().As<IProcessor>().Keyed<IProcessor>(typeof(ItemB).Name).InstancePerDependency();
builder.Register<Func<string, IProcessor>>(c => (s) => c.ResolveKeyed<IProcessor>(s));
builder.RegisterType<MyServiceConsumer>().As<IConsumer>();
var container = builder.Build();
var consumer = container.Resolve<IConsumer>().DoStuff(new ItemA()).Dump();
服务使用者。
public class MyServiceConsumer : IConsumer {
Func<string, IProcessor> processor;
public MyServiceConsumer(Func<string, IProcessor> processor) {
//processor.Dump("px");
this.processor = processor;
}
public string DoStuff(IItem item) {
return processor(item.GetType().Name).ProcessItem(item);
}
}
以下是接口。
public interface IConsumer { string DoStuff(IItem item); }
public interface IProcessor { string ProcessItem(IItem item); }
public interface IItem { string Name { get; } }
public interface IItemStrategy<in T> : IProcessor where T : IItem { string ProcessItem(T item); }
以下是具体的课程。
public class ItemA : IItem { public string Name { get { return "A"; } } public string UniqueA { get { return "+ UA"; } } }
public class ItemB : IItem { public string Name { get { return "B"; } } public string UniqueB { get { return "+ UB"; } } }
战略实施。 我希望我正确地应用模式,我确实想要强类型策略吗?
public class StrategyA : IItemStrategy<ItemA> {
string IProcessor.ProcessItem(IItem item) { Debug.Assert(item is ItemA); return this.ProcessItem((ItemA)item); }
public string ProcessItem(ItemA item) { return "PA " + item.Name + item.UniqueA; }
}
public class StrategyB : IItemStrategy<ItemB> {
string IProcessor.ProcessItem(IItem item) { Debug.Assert(item is ItemB); return this.ProcessItem((ItemB)item); }
public string ProcessItem(ItemB item) { return "PB " + item.Name + item.UniqueB; }
}
答案 0 :(得分:3)
我已经弄清楚了。
提示在这里autofac registration issue in release v2.4.5.724
var builder = new Autofac.ContainerBuilder();
builder.RegisterType<StrategyA>().As<IProcessor>().Keyed<IProcessor>(typeof(ItemA).Name).InstancePerDependency();
builder.RegisterType<StrategyB>().As<IProcessor>().Keyed<IProcessor>(typeof(ItemB).Name).InstancePerDependency();
builder.Register<Func<string, IProcessor>>(c => {
var ctx = c.Resolve<IComponentContext>();
return (s) => ctx.ResolveKeyed<IProcessor>(s);
});
builder.RegisterType<MyServiceConsumer>().As<IConsumer>();
var container = builder.Build();
var consumer = container.Resolve<IConsumer>().DoStuff(new ItemB()).Dump();
答案 1 :(得分:0)
我认为你在代码本身内部努力避免使用DI。打电话没问题。解决你的容器。
我会将以下方法声明添加到IItem:
IProcessor GetStrategy(IContainer container);
将以下实现添加到ItemA中:
public IProcessor GetStrategy(IContainer container)
{
return container.Resolve<StrategyA>();
}
以及以下对ItemB的实现:
public IProcessor GetStrategy(IContainer container)
{
return container.Resolve<StrategyB>();
}
最后,将MyServiceConsumer的构造函数更改为:
public MyServiceConsumer(IItem item, IContainer container)
{
this.item = item;
this.processor = item.GetStrategy(container);
}
更改您的来电者以传入容器,然后离开。如果您愿意,请将容器保持静止以避免将其传递,尽管这可能会影响可测试性。