How to use Autofac in a class library project?

18,974

Solution 1

You should only reference the container from the root of the application (global.asax). This is known as the Register Resolve Release pattern.

Your correct use of Constructor Injection ensures that you can reuse the NewsService class from other applications without requiring that those other applications use a particular DI Container (or any at all).

This is a good start at designing the service in a DI Friendly manner, yet keeping it container agnostic.

Solution 2

[TestClass]
public class LogTest 
{
    /// <summary>
    /// Test project: autofac impl.
    /// </summary>
    private readonly ContainerBuilder _builder; 
    private readonly IContainer _container;

    /// <summary>
    /// Initializes a new instance of the <see cref="LogTest" /> class.
    /// </summary>
    public LogTest()
    {
        //
        // Read autofac setup from the project we are testing
        //
        _builder = new ContainerBuilder();
        Register.RegisterTypes(_builder);
        _container = _builder.Build();

        loggingService = _container.Resolve<ILoggingService>(new NamedParameter("theType", this));
    }

    [TestMethod]
    public void DebugMsgNoExectption()
    {
        var a = _container.Resolve<IHurraService>();
        var b = a.ItsMyBirthday();

public class HurraService : IHurraService
{
    private IHurraClass _hurra;

    /// <summary>
    /// Initializes a new instance of the <see cref="HurraService" /> class.
    /// </summary>
    public HurraService(IHurraClass hurra)
    {
        _hurra = hurra;
    }

    /// <summary>
    /// It my birthday.
    /// </summary>
    public string ItsMyBirthday()
    {
        return _hurra.Hurra();
    }
}

public static class Register
{
    public static void RegisterTypes(ContainerBuilder builder)
    {
        builder.RegisterType<LoggingService>().As<ILoggingService>();
        builder.RegisterType<HurraService>().As<IHurraService>();
        builder.RegisterType<HurraClass>().As<IHurraClass>();
    }
}

Inside the Class Library I created the "Register" class. Here the Autofac setup is done. In my test project I read this file (Register.RegisterTypes) and init the _container.

Now I have access to Resolve all the goodies inside the project I am testing.

Solution 3

I guess it would depend on whether you intend to use the same assembly in multiple host applications. Does the assembly really require references to AutoFac? I would recommend against this, as if your requirements change later you would have a load of unnecessary references. Your host application should control how to assemble the modular parts, so I would leave configuration up to your host (in this case your web application. If you want to push some control of registration, you could create a type which handles the registration for you, but as I mentioned before, your assembly is essentially bound to using AutoFac e.g.:

public static class NewsRegistration()
{
    public static void RegisterTypes(ContainerBuilder builder)
    {
        // Register your specific types here.
        builder.RegisterType<NewsService>().As<INewsService>();
    }
}

That way you could easily call:

var builder = new ContainerBuilder();
// Register common types here?

NewsRegistration.RegisterTypes(builder);

var container = builder.Build();
Share:
18,974

Related videos on Youtube

Brendan Vogt
Author by

Brendan Vogt

Wedding photographer and videographer from Paarl, South Africa. Join me on my new adventure in wedding photography and videography at Brendan Vogt Photo &amp; Video.

Updated on March 31, 2020

Comments

  • Brendan Vogt
    Brendan Vogt over 3 years

    I have the following implementation:

    private INewsRepository newsRepository;
    
    public NewsService(INewsRepository newsRepository)
    {
         this.newsRepository = newsRepository;
    }
    

    This service is in a separate project than that of my web project. Where and how would I specify the dependency injection? Would I still need to put it in my global.asax file? What if this service is used my other apps as well?

Related