2016-08-17 86 views
1

我们有一个ASP.NET项目,我们使用AutoFac到DI。 我们有一个包含所有数据库查询的服务层,我们需要在静态类中进行一些查询。静态类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>(); 
    ... 
} 

另外,它将如何在非静态类和静态类?

在此先感谢。

+2

你不能(也不应该)注入静态类。想想当2个Web请求同时进入并尝试访问相同的上下文对象时会发生什么。相反,为什么不通过服务作为参数? – DavidG

+0

好的,如果班级不是静态的呢?我怎样才能做到这一点?我想要的是,我可以在不知道里面发生了什么的情况下调用类中的方法,因为我需要从数据库中检索信息,所以我需要调用一个服务(或多个),但我不想担心这些班级以外的服务......因为我只想调用它并获取信息。 –

+0

您的静态类在请求的生命周期中位于何处?如果它在'Controller'中的某个地方被调用,按照DavidG的说法:将该函数声明为'public static Test(IService1 service1)',并从'Controller'传入'service1'。 –

回答

3

问题是我必须从不同的地方调用许多这些类,并且我不想依靠有服务来调用该类,我希望该类负责处理所有事情。

在这种情况下,使得它得到它的依赖注入您应该注册Autofac类:

builder.RegisterType<MyClass>(); 

如果该类一个请求时多次使用它可能是使用注册它有用InstancePerLifetimeScope(),但这取决于您的整体架构。有关更多信息,请参见此link Autofac文档。

当然,你必须改变你的类,这样的方法不是静态的更多,并添加一个构造函数来获取相关性:

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

伟大的解决方案,但我已经尝试过这种解决方案,我不需要用AutoFac注册我的课程,剩下的我也一样。谢谢。 –