2016-08-17 61 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註冊我的課程,剩下的我也一樣。謝謝。 –