我有一个像这样的接口和类
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实现 在这个类中,它有自己的属性,并从其load方法加载该属性。
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
}
}
答案 0 :(得分: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();
答案 1 :(得分:0)
您可以调用其他类似的实现
在包含接口ICustomerEx
的程序集中,您可以添加一个存储ICustomerEx
实例的注册表类
(注意这是伪代码以显示它是如何进行的。)
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);
}
}