2015-07-20 70 views
1

This answer顯示瞭如何使用不帶參數的工廠接口來解析實例。如何在具有參數的簡單噴油器中實現工廠接口

我使用下面的代碼

public interface ISimpleBarFactory 
{ 
    Bar CreateBar(int value); 
} 

public sealed class SimpleBarFactory : ISimpleBarFactory 
{ 
    private readonly Container _container; 
    public SimpleBarFactory (Container container) 
    { 
     _container = container; 
    } 

    public Bar CreateBar(int value) 
    { 
     _container.Register(() => new Bar(vlue)); 
     return _container.GetInstance<Bar>(); 
    } 
} 

解決具有構造函數的參數情況。

The container can't be changed after the first call to GetInstance, GetAllInstances and Verify.

這是解決使用工廠接口與參數情況下,正確的做法:

然而,使用工廠來實例化服務類,當我得到下面的異常?

更新

以下是我的代碼。我正在從Ninject遷移代碼。

public interface IFormsUIFactory 
{ 
    AccountUI CreateAccountUI(Account account); 
} 

public class FormsUIFactory 
{ 
    private readonly IFormsUIFactory _uiFactory; 
    public FormsUIFactory(IFormsUIFactory uiFactory) 
    { 
     _uiFactory = uiFactory; 
    } 

    public void CreateAccountUI(Account account) 
    { 
     _uiFactory.CreateAccountUI(account); 
    } 
} 

UI類將被注入

public partial class AccountUI : Form 
{ 
    private readonly IAccountMaintenanceProcessor _processor; 
    private readonly Account _account; 
    public AccountUI(IAccountMaintenanceProcessor accountProcessor, Account account) 
    {  
     _processor = accountProcessor; 
     _account = account; 
    } 

} 

實例化代碼:

var account = new Account(); 
// Populate values for the account 

var frm = _uiFactory.CreateAccountUI(account); 
+1

您使用的是什麼IoC? –

+0

關鍵是你應該在應用程序啓動時只註冊'Bar' ** **一次**。並使用像動態參數解析來傳遞'value'。您需要知道您使用的是哪種IoC,因爲每個IoC都有不同的方式(語法) –

+0

我正在使用簡單噴油器 – kagundajm

回答

1

您有由事實,你是混合運行時數據造成的問題(你Account)對象,與組件。您的DI容器負責構建組件的對象圖。這些組件通常應該是無狀態的,並且運行時數據應該使用方法調用流過對象圖。將運行時數據注入到組件的構造函數中,使這些組件變得有狀態並以多種不同方式使應用程序複雜化;你目睹了今天這些複雜情況之一。但是這樣做有很多缺點。例如,將運行時數據注入構造函數使得無法驗證您的對象圖(使用自動化測試),並且使您的應用程序在運行時很容易中斷。因此,這決不是Simple Injector特有的,但Simple在解決服務時不允許傳遞運行時值,從而使問題更加突出。 你可以找到關於這個here的詳細解釋。

因此,儘量讓組件儘可能保持無狀態,並至少將運行時數據保留在構造函數之外。實現此目的的一種簡單方法是在表單中添加一個屬性,以允許設置您正在使用的實體。通用接口可以被添加到一個表單,允許這樣的:

interface IForm<TEntity> 
{ 
    TEntity Entity { get; set; } 
} 

此通用接口可以在IFormFactory抽象使用:

interface IFormFactory 
{ 
    TForm CreateFormFor<TForm, TEntity>(TEntity entity) 
     where TForm : Form, IForm<TEntity>; 
} 

創造IFormFactory的實現是那麼容易,因爲這樣的:

public class FormFactory : IFormFactory 
{ 
    private readonly Container container; 

    public FormFactory(Container container) { 
     this.container = container; 
    } 

    public TForm CreateFormFor<TForm, TEntity>(TEntity entity) 
     where TForm : Form, IForm<TEntity> { 
     var form = this.container.GetInstance<TForm>(); 
     form.Entity = entity; 
     return form; 
    } 
} 
+0

感謝您的幫助和澄清。我從來沒有意識到注入運行時數據有很多缺點。 – kagundajm

相關問題