Chris
Chris

Reputation: 373

Autofac Property Inject issues

I am using MVC with EF and Autofac. I have a concrete class called Helper. Helper is in another DLL and not the main MVC web application.

It has a property of type DBContext called 'Context'.

I want to inject an instance of the DBContext into this property - however its always null.

Here is what I have so far in GLobal:

    var output = new DbContext(connectionString);
    builder.RegisterInstance(output).As<DbContext>().PropertiesAutowired();
             builder.RegisterType<Helper().WithParameter("Context",output).PropertiesAutowired();

        // Set the dependency resolver to be Autofac.
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Context is the property on the Helper class which I would like injected with the instance 'output'.

Context is always null.

Upvotes: 2

Views: 1390

Answers (1)

Alberto Chiesa
Alberto Chiesa

Reputation: 7360

In Autofac, the easiest way to manage dependencies is to leverage constructor injection.

Basically, instead of telling Autofac "wire up the properties for me and do your mojo", you tell him to let YOU in charge of declaring the list of components.

So, instead of wondering why property injection is not working, declare explicitly your dependencies in Helper constructor:

public class Helper
{
    public DbContext Context { get; private set; }

    public Helper(DbContext context /* Autofac is going to fill in this */)
    {
        Context = context;
    }
}

Then, in Global (or in some other class encapsulating your registrations) you just tell Autofac to look at the Helper type and try his best to call the best constructor, which is the simplest thing you can do:

// Either InstancePerDependency, or SingleInstance, or something else depending upon you requirements.
builder.RegisterType<Helper>().AsSelf().InstancePerDependency();

And you should be done: Autofac will search for the constructor with most parameters (and there will be only one with a parameter of type DbContext and will check if he knows how to create parameters for the requested type (which he can).

So, voilà, you get a ready to use Helper!

Edit: I'm keeping the example above, because it's the correct answer to the question, BUT, to reply to the comment, I would use a little more machinery, in the form of an Init method:

public class Helper
{
    public DbContext Context { get; private set; }

    public Init(DbContext context /* Autofac is going to fill in this */)
    {
        Context = context;
    }
}

And you can instruct Autofac to call this method during object initialization:

builder.RegisterType<CustomHelper>()
       .AsSelf()
       .InstancePerDependency()
       .OnActivating(h => {
            var dbContext = h.Context.Resolve<DbContext>();
            ((Helper)h.Instance).Init(dbContext);
        });

OnActivating lets you write the explicit initialization call. Keep in mind you probably want to register all the types in an assembly which derive from Helper, but probably that is for another question.

Upvotes: 8

Related Questions