2012-10-10 56 views
0

當試圖向當前正在註冊的依賴項注入一個依賴項時出現問題。我有一個應用程序,它可以在引導加載程序開始時從設置文件讀取,然後使用此設置文件中特定值的反射創建對象。我會盡量讓代碼在這裏說話。Autofac - 未找到類型'X'的構造函數

設置文件

設置文件是一個普通的舊的XML文件,序列化/反序列化到名爲BootstrapSettings一個對象,它符合下列合同:

public interface IBootstrapSettings 
{ 
    string Get(string key); 
    void Set(string key, string value); 
} 

在此設置文件,我有一個特定的密鑰,用於標識我打算用於此應用程序的IEncryptor,此刻我可以選擇PlainTextEncryptorTDESEncryptor,後者從設置文件中讀取密碼短語,因此我在它的構造函數中,我傳遞IBootstrapSettings的實例以從設置文件中讀取此密碼。目前我正在向每個加密器注入IBootstrapSettings的實例 - 即使PlainTextEncryptor未使用它。我這樣做是因爲我不得不使用反射來創建此實例,並且不知道如何區分不帶參數的構造函數和創建類型時的構造函數(但這是另一個問題我想)。

IEncryptor構造

以下是各IEncryptor我目前擁有的構造函數。

public sealed class PlainTextEncryptor : IEncryptor 
{ 
    private readonly IBootstrapSettings _bootstrapSettings; 

    public PlainTextEncryptor(IBootstrapSettings bootstrapSettings) 
    { 
     _bootstrapSettings = bootstrapSettings; 
    } 
} 

public sealed class TDESEncryptor : IEncryptor 
{ 
    private readonly IBootstrapSettings _bootstrapSettings; 

    public TDESEncryptor(IBootstrapSettings bootstrapSettings) 
    { 
     _bootstrapSettings = bootstrapSettings; 
    } 
} 

注射

走上我怎麼設置我的依賴關係。我有別的創建之前創建的引導依賴的Autofac模塊 - 它看起來像這樣:

public sealed class BootstrapSettingsModule : Autofac.Module 
{ 
    private readonly string _filePath; 

    public BootstrapSettingsModule(string filePath) 
    { 
     _filePath = filePath; 
    } 

    protected override void Load(ContainerBuilder builder) 
    { 
     base.Load(builder); 

     builder.Register(c => new BootstrapSettings(_bootstrapSettingsPath)) 
      .As<IBootstrapSettings>() 
      .SingleInstance(); 

     builder.Register(c => (IEncryptor)Activator.CreateInstance(Type.GetType(c.Resolve<IBootstrapSettings>().Get("encryptionprovider")), args: new { bootstrapSettings = c.Resolve<IBootstrapSettings>() })) 
      .As<IEncryptor>() 
      .SingleInstance(); 
    } 
} 

現在這個執行很好,當我嘗試.ResolveIEncryptor一個實例,我得到的錯誤出現問題未找到類型'任何加密類型'的構造函數。我認爲這是因爲Autofac無法解決我的IBootstrapSettings,並且因爲我的IEncryptor上沒有默認的無參數構造函數,所以它是合適的。

我在這裏做什麼有點損失,我是否通過指定IBootstrapSettings作爲單個實例做錯了什麼...或者我只是不明白Autofac的綁定正確嗎?一如既往地欣賞任何幫助!

+0

請顯示加密器類的構造函數。 –

+0

@DanielHilgarth更新了構造函數代碼。 –

回答

2

我不明白你爲什麼不只是使用Autofac的設施。

protected override void Load(ContainerBuilder builder) 
{ 
    base.Load(builder); 

    var settings = new BootstrapSettings(_bootstrapSettingsPath); 
    builder.RegisterInstance(settings) 
     .As<IBootstrapSettings>() 
     .SingleInstance(); 

    var encryptorType = Type.GetType(settings.Get("encryptionprovider")); 
    builder.RegisterType(encryptorType) 
     .As<IEncryptor>() 
     .SingleInstance(); 
} 

這會給你額外的好處,你會不會需要有一個構造在每一個加密的IBootstrapSettings參數。你只需要那些真正使用該參數的人就可以了。

+0

非常棒!我是Autofac的新手,並不知道我可以使用'RegisterType'而不是反射來做我想做的事。這非常感謝很多!它說我可以在3分鐘內接受答案,所以會做。 –

相關問題