2017-02-15 51 views
0

我在MVC項目中使用autofac。 我有另一個項目與核心業務(DLL庫)。 在這個核心,我想使用autofac檢索一些接口。現在在項目庫中使用autofac

,如果我在MVC應用程序是,我可以使用

DependencyResolver.Current.GetService<IMyService>(); 

爲獲取服務。 但是在圖書館中,我怎樣才能檢索服務而無需將它作爲某些類聲明中的屬性傳遞?

DependencyResolver僅在MVC項目中定義。

這是最佳做法嗎?

+2

一些有用的閱讀材料:http://blog.ploeh.dk/2014/05/19/di-friendly-library/和http://blog.ploeh.dk/2014/05/19/ di-friendly-framework/ – trailmax

+0

感謝trailmax! – user3401335

+1

@trailmax:這些帖子實際上是在可複用的庫上,比如NuGet包。這個問題是關於同一解決方案中的庫(或項目)。我認爲這個問題更多的是http://blog.ploeh.dk/2011/07/28/CompositionRoot/和這個https://stackoverflow.com/questions/9501604/ioc-di-why-do-i-有 - 參考-所有層組件 - 在進入的應用程序。 – Steven

回答

2

我看到你的方法如下問題:

  1. DepdencyResolverSystem.Web.Mvc定義,你的BL-項目不應引用組裝。
  2. 您在使用Service Locator Pattern,這是declared an Anti-Pattern

避免System.Web.Mvc依賴性在BL-項目

我發現了一個特定Locator<T>是一個可行的方法,它繞行「開一切」 - 和 -issue服務定位器模式:

public interface ILocator<T> // defined in some *CORE* project 
{ 
    T Locate(); 
} 

public class AutofacLocator<T> : ILocator<T> // defined and injected in your *FRONTEND* project 
{ 
    public AutofacLocator(ILifetimeScope lifetimeScope) 
    { 
    this.LifetimeScope = lifetimeScope; 
    } 

    public virtual T Locate() 
    { 
    var service = this.LifetimeScope.Resolve<T>(); 

    return service; 
    } 
} 

這可以簡單地被登記爲open generic

builder.RegisterGeneric(typeof(AutofacLocator<>)) 
     .As(typeof(ILocator<>)) 
     .InstancePerDependency(); 

因此,而不是依賴於靜態DependencyResolver.Current,創建自己的解析器,並在BL-類注射它構造函數:

public class SomeBusinessLogic 
{ 
    public SomeBusinessLogic(ILocator<SomeDependency> someDependencyLocator) 
    { 
    } 
} 

使用構造函數,注射,而不是服務定位器模式

另一種方法是簡單地定義作爲ctor參數的作爲依賴關係的實例,然後讓Autofac構建BL類的實例:

public class SomeBusinessLogic // defined in your *BL* project 
{ 
    public SomeBusinessLogic(SomeDependency someDependency) 
    { 
    } 
} 

var someBusinessLogic = DependencyResolver.Current.GetService<SomeBusinessLogic>(); // in your *FRONTEND* project