在不同的程序集中实现接口
本文关键字:集中 实现 接口 程序集 程序 | 更新日期: 2023-09-27 18:21:12
我有一个类似的接口和类
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
}
}
这取决于您想要什么。使用现在的独立类,您需要将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();
您可以调用其他类似的实现
在包含接口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);
}
}