静态类中的AutoFac DI

时间:2016-08-17 11:35:41

标签: asp.net-mvc dependency-injection autofac

我们有一个ASP.NET项目,我们将AutoFac用于DI。 我们有一个包含所有数据库查询的服务层,我们需要在静态类中进行一些查询。

这是我们在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();
    }
}

这就是我们在控制器中访问的方式:

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);
    }
}

现在我们需要在静态类中检索数据库中的数据,所以我们必须调用我们的服务层,但是我们不知道怎么做...我们已经看到了这个,但我不知道如果它是正确的,但它确实有效。

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

此外,它在非静态和静态类中的表现如何?

提前致谢。

1 个答案:

答案 0 :(得分:3)

  

问题是我必须从不同的地方调用许多这些课程,我不想依赖于提供服务来打电话给课程,我希望班级能够照顾好一切。

在这种情况下,您应该使用Autofac注册您的类,以便它注入依赖项:

builder.RegisterType<MyClass>();

如果在单个请求期间多次使用该类,则使用InstancePerLifetimeScope()注册它可能很有用,但这取决于您的整体架构。有关详细信息,请参阅Autofac文档中的link

当然你必须改变你的类,以便方法不再是静态的,并添加一个构造函数来获取依赖项:

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
    }
}

现在,您可以在控制器中注入MyClass依赖项并使用它,而无需了解有关其内部或其依赖项的任何信息:

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);
    }
}