What is the proper way to create objects which require parameters using autofac?

此生再无相见时 提交于 2019-12-07 06:54:28

The way to fix this problem is the following:

Change WidgetFactory to define a delegate for creating widgets:

public class WidgetFactory
{
    public delegate IWidget Create(int firstParam, double secondParam);
}

In your autofac module, wire up the factory using the RegisterGeneratedFactory method. 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:

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.
  • 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.

There is robust documentation on all of these options with examples over at the Autofac documentation site:

You would inject dependencies into your factory with an IoC container using constructor or property injection, not args into a method. 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:

var builder = new ContainerBuilder();
var xmlFileName = HttpContext.Current.Server.MapPath(
    ConfigurationManager.AppSettings["xmlData"]);

builder.Register(c => new XmlAdvertisementRepository(new XmlContext(xmlFileName)))
    .AsImplementedInterfaces()
    .InstancePerHttpRequest();
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!