[英]What is the proper way to create objects which require parameters using autofac?
I think I get most things about dependency inversion and using an IoC container, but one thing still does not appear clear to me. 我想我了解了有关依赖倒置和使用IoC容器的大多数信息,但对我来说仍然不清楚。 How do I use autofac to automate the following factory:
如何使用autofac自动化以下工厂:
public class WidgetFactory
{
public static IWidget Create(int foo, double bar)
{
return new Widget(foo, bar);
}
}
public class Widget
{
private readonly int foo;
private readonly double bar;
public Widget(int foo, double bar)
{
this.foo = foo;
this.bar = bar;
}
}
elsewhere... 别处...
public class FoobarUser
{
public void Method()
{
var widget = WidgetFactory.Create(3, 4.863);
// Do something with my widget
// Possibly add it to a widget collection
}
}
Basically, I need thousands of widgets to be created and I'm not sure of the best way of doing so. 基本上,我需要创建成千上万个小部件,但我不确定这样做的最佳方法。 How would I create the widget factory using autofac and how would I use that in Method, bearing in mind that Method does not contain a reference to the IContainer?
考虑到Method不包含对IContainer的引用,我如何使用autofac创建小部件工厂,以及如何在Method中使用它?
The way to fix this problem is the following: 解决此问题的方法如下:
Change WidgetFactory to define a delegate for creating widgets: 更改WidgetFactory以定义用于创建窗口小部件的委托:
public class WidgetFactory
{
public delegate IWidget Create(int firstParam, double secondParam);
}
In your autofac module, wire up the factory using the RegisterGeneratedFactory method. 在您的autofac模块中,使用RegisterGeneratedFactory方法连接工厂。 This will automatically create your factory for you:
这将自动为您创建工厂:
public class TestClassModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterType<Widget>().As<IWidget>();
builder.RegisterGeneratedFactory<WidgetFactory.Create>(new TypedService(typeof(IWidget)));
builder.RegisterType<FoobarUser>();
}
}
Inject the factory into FoobarUser: 将工厂注入FoobarUser:
public class FoobarUser
{
private readonly WidgetFactory.Create factory;
public FoobarUser(WidgetFactory.Create factory)
{
this.factory = factory;
}
public void Method()
{
var widget = this.factory(3, 4.836);
// Do something with my widget
// Possibly add it to a widget collection
}
}
There are basically two ways to handle parameters: 基本上有两种方法可以处理参数:
Register(c => T)
) or you can append parameters to reflection-based ( RegisterType<T>
) registrations. Register(c => T)
)中提供它们,也可以将参数附加到基于反射的RegisterType<T>
( RegisterType<T>
)中。 Resolve<T>()
calls or you can use delegate factories or Func<T>
dependencies to dynamically create a factory method that can be used by your component. Resolve<T>()
调用中,也可以使用委托工厂或Func<T>
依赖项来动态创建可由组件使用的工厂方法。 There is robust documentation on all of these options with examples over at the Autofac documentation site: 在所有这些选项上都有可靠的文档,并在Autofac文档站点上提供了示例:
You would inject dependencies into your factory with an IoC container using constructor or property injection, not args into a method. 您将使用构造函数或属性注入将依赖项通过IoC容器注入工厂,而不是将args注入方法。 If you needed to inject specific values as parameters into your service's constructor, you could set that up during registration similar to the below code.
如果需要将特定值作为参数注入服务的构造函数中,则可以在注册过程中类似于以下代码进行设置。
Here, I'm getting a XML file path from my web.config and passing that value into my repository's constructor: 在这里,我从web.config获取XML文件路径,并将该值传递到存储库的构造函数中:
var builder = new ContainerBuilder();
var xmlFileName = HttpContext.Current.Server.MapPath(
ConfigurationManager.AppSettings["xmlData"]);
builder.Register(c => new XmlAdvertisementRepository(new XmlContext(xmlFileName)))
.AsImplementedInterfaces()
.InstancePerHttpRequest();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.