2013-07-06 50 views
1

我有這樣在不同的組件實現的接口

public interface ICustomerEx 
{ 
    void Load(DataRow row); 
} 

public class Customer:ICustomerEx 
{ 
    public string Name{get;set;} 
    public string Address{get;set;} 

    void Load(DataRow row) 
    { 
    Name = (string)row["name"]; 
    Address = (string)row["address"]; 
    } 
} 

現在我建立這是一個類庫,並添加到另一個項目作爲參考的接口和類。 在該項目中有一個名爲UiCustomer的類,它使用相同的引用接口實現ICustomerEx 在此類中,它具有自己的屬性並從其加載方法加載該屬性。

public class UiCustomer:ICustomerEx 
{ 
    public string Telephone{get;set;} 

    void Load(DataRow row) 
    { 
    Telephone=(string)row["tele"]; 
    } 
} 

現在有沒有什麼辦法來實現我的第一類的(即構建一個類庫)Load方法加載它通過使用像依賴注入的自身屬性後加載UI項目的屬性。

例如。

public class Customer:ICustomerEx 
{ 
    public string Name{get;set;} 
    public string Address{get;set;} 

    void Load(DataRow row) 
    { 
    Name = (string)row["name"]; 
    Address = (string)row["address"]; 

    //Call load methods in other places that Interface implemented 
    } 
} 

回答

2

這取決於你想要的。如果您現在使用單獨的類,則需要將ICustomerEx對象的列表依賴注入到每個Customer中,但是最終會生成一堆不同的對象,每個對象只會包含相關屬性的子集。這聽起來像繼承+模板方法模式可能是更好的選擇:

public class Customer:ICustomerEx 
{ 
    public string Name{get;set;} 
    public string Address{get;set;} 

    void Load(DataRow row) 
    { 
     this.Name = (string)row["name"]; 
     this.Address = (string)row["address"]; 
     this.DoMoreLoading(row); 
    } 

    // this method is defined as a no-op in the base class, but it provides an extension point 
    // for derived classes that want to load additional properties 
    protected virtual void DoMoreLoading(DataRow row) { } 
} 

// note that now UiCustomer extends Customer (and thus still implements ICustomerEx 
public class UiCustomer : Customer 
{ 
    public string Telephone { get; set; } 

    protected override void DoMoreLoading(DataRow row) 
    { 
     this.Telephone = (string)row["tele"]; 
    } 
} 

// usage 
var uiCustomer = new UiCustomer(); 
uiCustomer.Load(row); // populates name, addr, and telephone 

爲了支持實例在庫邊的客戶,你需要一些方法,使圖書館意識到UiCustomer類的。要做到這一點

一種方法是與IOC容器註冊一個ICustomerEx,然後使用依賴注入解決實例:

// in the UI code (this is code for the Autofac IOC container): 
ContainerBuilder cb = ... 
cb.RegisterType<UiCustomer>().As<ICustomerEx>(); 
cb.RegisterType<AServiceThatNeedsACustomer>(); 

// in the library code 
public class AServiceThatNeedsACustomer { 
    private readonly ICustomerEx customer; 
    // the customer will get injected by the IOC container 
    public AServiceThatNeedsACustomer(ICustomerEx customer) { 
     this.customer = customer; 
    } 
} 

或者,你可以使用一個工廠模式:

// in the library: 
public static class CustomerFactory { 
    private static volatile Func<ICustomerEx> instance =() => new Customer(); 
    public static Func<ICustomerEx> Instance { get { return instance; } set { instance = value; } }   
} 

// then to get a customer 
var cust = CustomerFactor.Instance(); 
cust.Load(row); 

// in the UI code: 
CustomerFactory.Instance =() => new UiCustomer(); 
+0

感謝您的回覆。我的要求與你的答案有一點不同。這個客戶實例需要從參考DLL一側創建。即從客戶類別存在的同一個程序集中的一個類。我的要求是創建通用類庫來創建客戶實例並加載它。除此之外,當它引用任何程序集時,它應該能夠從引用的程序集中加載它自己的屬性。 – Snj

+0

@Snj:我已經更新了我的答案,以包含關於如何做到這一點的一些想法。 – ChaseMedallion

+0

感謝您的想法。用你的方式,當cust實例創建時,它只有'電話'成員。即當我從顧客類中看到它時,它只包含子類的成員。客戶的成員,如'姓名','地址'不包括在內。 – Snj

0

你可以這樣呼叫其他實現

在包含接口ICustomerEx的程序集中,您可以添加一個registr存儲的ICustomerEx情況下,這樣的

Y系(請注意,這是僞代碼,以顯示它如何能走了。)

public class CustomerRegistry : ICustomerEx { 
    // singelton 
    public static final CustomerRegistry theRegistry = new CustomerRegistry(); 

    private ArrayList<ICustomerEx> customers = new ArrayList<ICustomerEx>(); 
    public void RegisterCustomer(ICustomerEx customer) { 
     customers.add(customer); 
    } 

    public void Load(DataRow row) 
    { 
     foreach(ICustomerEx customer in customers) { 
      customer.Load(row); 
     } 
    } 
} 

ICustomerEx的每個執行需要調用註冊表

CustomerRegistry.theRegistry.RegisterCustomer(new UiCustomer()); 

在您的主要客戶類中使用註冊表調用其他負載

public class Customer:ICustomerEx 
{ 
void Load(DataRow row) 
{ 
    CustomerRegistry.theRegistry.Load(row); 
} 
}