John Mathison
John Mathison

Reputation: 914

AutoFac DI in static class

We have a ASP.NET project, and we use AutoFac to DI. We have a Service layer with all database queries and we need to make some queries in a static class.

This is how we register the dependencies in the Global.asax:

public class Dependencies
{
    public static void RegisterDependencies()
    {
        var builder = new ContainerBuilder();

        builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();

        builder.RegisterModule(new ServiceModule());
        builder.RegisterModule(new EfModule());

        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}

public class ServiceModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyTypes(Assembly.Load("MyApp.Service")).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
    }

}

public class EfModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType(typeof(myDataContext)).As(typeof(IMyContext)).InstancePerLifetimeScope();
    }
}

And this is how we access in the controller:

public class SomeController : Controller
{
    private readonly IService1 _service1;
    private readonly IService2 _service2;

    public SomeController(IService1 service1, IService2 service2)
    {
        _service1 = service1;
        _service2 = service2;
    }


    public ActionResult Index()
    {
        var service = _service1.GetAll();
        ...

        return View(searchModel);
    }
}

Now we need to retrieve data from the database in a static class, so we have to call our service layer, but we don't know how to do it...we have seen this, but I don't know if it is correct, but it works.

public static Test ()
{
    ...
    var service1 = DependencyResolver.Current.GetService<IService1>();
    ...
}

Also, how it would be in both, non-static and static classes?

Thanks in advance.

Upvotes: 1

Views: 6244

Answers (1)

fknx
fknx

Reputation: 1785

The problem is I have to call many of those classes from different places and I don't want to depend on having the service in order to call the class, I'd like the class to take care of everything.

In this case you should register your class with Autofac so that it gets its dependencies injected:

builder.RegisterType<MyClass>();

If the class is used several times during a single request it might be useful to register it using InstancePerLifetimeScope(), but that depends on your overall architecture. See this link to the Autofac documentation for more information.

Of course you have to change your class so that the methods are not static any more and add an constructor to get the dependencies:

public class MyClass
{
    private readonly IService1 _service1;

    public MyClass(IService1 service1) 
    {
        _service1 = service1;
    }

    public void Test
    {
        // use the _service1 instance to do whatever you want
    }
}

Now you can inject the MyClass dependency in your controller and use it without having to know anything about its internals or its dependencies:

public class SomeController : Controller
{
    private readonly IService1 _service1;
    private readonly IService2 _service2;

    private readonly MyClass _myClass;

    public SomeController(IService1 service1, IService2 service2, MyClass myClass)
    {
        _service1 = service1;
        _service2 = service2;
        _myClass = myClass;
    }


    public ActionResult Index()
    {
        var service = _service1.GetAll();
        ...

        _myClass.Test();

        return View(searchModel);
    }
}  

Upvotes: 3

Related Questions