2017-06-23 85 views
0

我一直在瀏覽Autofac的示例和文檔,並且無法看到使其工作。使用Autofac進行屬性注入不起作用

我們有一個輔助類,Core.Helpers.Tokens與建立這樣的特性:

namespace Core.Helpers 
{ 
    public static class Tokens 
    { 
     private static IConfigurationManager ConfigurationManager; 

     public static string GetToken() 
     { 
      var sessionTokenName = ConfigurationManager.GetAppSetting("SessionTokenName"); 
      return (string) HttpContext.Current.Session[sessionTokenName]; 
     } 
    } 
} 

配置是這樣設計的:

namespace Core.Config 
{ 
    public interface IConfigurationManager 
    { 
     //... 
    } 

    public class WebConfigConfigurationManager : IConfigurationManager 
    { 
     //... 
    } 
} 

在我們的MVC的Web應用程序(其中引用和用途Core.HelpersStartup.cs我試圖爲房地產注入註冊IConfigurationManager

public partial class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var builder = new ContainerBuilder(); 

     // REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED 
     builder.RegisterControllers(typeof(MvcApplication).Assembly); 
     builder.RegisterModule<AutofacWebTypesModule>(); 
     builder.RegisterFilterProvider(); 
     builder.RegisterType<WebConfigConfigurationManager>().As<IConfigurationManager>().PropertiesAutowired(); 

     RegisterTypes(builder); 

     // BUILD THE CONTAINER 
     var container = builder.Build(); 
     var webConfig = container.Resolve<IConfigurationManager>(); 

     // REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     // REGISTER WITH OWIN 
     app.UseAutofacMiddleware(container); 
     app.UseAutofacMvc(); 
    } 

當Web代碼調用GetToken時,ConfigurationManager爲空。我錯過了什麼?

回答

1

一個錯誤是,您的Tokens.ConfigurationManager是私人領域,而屬性注入與公共屬性一起使用。

此外,它必須是一個實例屬性,而不是靜態的。那麼到底應該

public IConfigurationManager ConfigurationManager{get;set;} 

但是,這將意味着你也不得不注入令牌實例,這將使不再是一個靜態輔助類,你就必須做一些重新設計,有有一些選擇:

  1. 如果你有一個IConfigurationManager實例無處不在,你期望調用從您GetTokens可以傳遞,在作爲輸入參數GetTokens()
  2. 您推廣這種靜態輔助的依賴關係(例如ITokenService ?)將被注入到需要的任何地方。您可以使用Autofac生命週期管理使其成爲一個單身人士,而不是將其設爲靜態, 。 (也許是最好的解決方案)
  3. 最差解決方案,但最小的變化,一個不必放棄這是一個靜態輔助類的工作,是使物業使用DependencyResolver代替注射,像:

    私有靜態IConfigurationManager ConfigurationManager中{{返回DependencyResolver.Current.GetService();}}

+0

好的,我可以看到它需要公開。但是你不能在靜態類中聲明實例成員。 –

+0

爲什麼第三名會是最差的? –

+0

第三種解決方案實質上是放棄DI並降級使用Service Locator,它有很多缺點,有些甚至認爲它是反模式。 https://stackoverflow.com/questions/1557781/whats-the-difference-between-the-dependency-injection-and-service-locator-patte – Loonquawl

0

您解決IConfigurationManager,你應該解決WebConfigConfigurationManager。

如果您有5個使用IConfigurationManager的類,解析該接口並不會告訴autoface您想要使用哪個具體的類,該類具有此接口。

+0

當我嘗試解決'var webConfig = container.Resolve ();''我得到:類型'Autofac.Core的異常。Registration.ComponentNotRegisteredException'發生在Autofac.dll中,但未在用戶代碼中處理 附加信息:所請求的服務'Clark.Chains.Core.Config.WebConfigConfigurationManager'尚未註冊。 –