简体   繁体   English

使用autofac创建需要参数的对象的正确方法是什么?

[英]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: 基本上有两种方法可以处理参数:

  • At registration time - you can provide them in lambda registrations ( Register(c => T) ) or you can append parameters to reflection-based ( RegisterType<T> ) registrations. 在注册时-您可以在lambda注册( Register(c => T) )中提供它们,也可以将参数附加到基于反射的RegisterType<T>RegisterType<T> )中。
  • At resolve time - you can either append parameters to 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.

相关问题 创建Observable的正确方法是什么,该Observable将流读取到最后 - What is the proper way to create an Observable which reads a stream to the end 将运行时构造函数参数传递给Autofac的最佳方法是什么? - What is the best way to pass runtime constructor parameters to Autofac? Autofac使用通用对象作为非通用参数 - Autofac using generic objects as non-generic parameters 与对象比较哪种方法更好/更合适? - Which way is better/proper to compare to objects? 在 Clean Architecture 中为 Autofac 实现 Serilog 上下文记录器注入的正确方法是什么? - What is the proper way to implement Serilog Contextual logger injection for Autofac in Clean Architecture? 在WPF中创建UI设置的正确方法是什么? - What is the proper way to create UI settings in WPF? 什么是创建等效功能的正确方法 - What is a proper way to create awaitable function 用颜色创建画笔的正确方法是什么? - What is the proper way to create a brush from a color? 在MVC中创建ASPX视图的正确方法是什么? - What is the PROPER way to create an ASPX View in MVC? 创建和处置系统计时器的正确方法是什么? - What is the proper way to create and dispose a system timer?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM