C# 在不同程序集中实现接口
我有一个这样的接口和类C# 在不同程序集中实现接口,c#,interface,C#,Interface,我有一个这样的接口和类 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"]; Addres
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的类,它从相同的引用接口ICCustomerEx实现
在这个类中,它有自己的属性,并从其加载方法加载该属性
public class UiCustomer:ICustomerEx
{
public string Telephone{get;set;}
void Load(DataRow row)
{
Telephone=(string)row["tele"];
}
}
现在有什么方法可以实现我的第一个类(作为类库构建)的Load方法,在使用依赖项注入加载Ui项目自己的属性之后再加载它的属性
例如
这取决于你想要什么。像现在这样使用单独的类,您需要向每个客户中注入一个ICCustomerEx对象的依赖关系列表,但最终会得到一堆不同的对象,每个对象都只有相关属性的子集。听起来继承+模板方法模式可能更适合:
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容器注册ICCustomerEx,然后使用依赖项注入解析实例:
// 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;
}
}
//在UI代码中(这是Autofac IOC容器的代码):
容器生成器cb=。。。
cb.RegisterType().As();
cb.RegisterType();
//在库代码中
需要客户的公共类服务{
私有只读ICCustomerEx客户;
//客户将通过IOC容器进行注射
需要客户的公共服务(ICCustomerEx客户){
this.customer=customer;
}
}
或者,您可以使用factory模式:
// 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();
//在库中:
公共静态类CustomerFactory{
私有静态volatile Func实例=()=>new Customer();
公共静态Func实例{get{return Instance;}set{Instance=value;}}
}
//然后去找一个顾客
var cust=CustomerFactor.Instance();
客户负载(世界其他地区);
//在UI代码中:
实例=()=>新UiCustomer();
您可以这样调用其他实现
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"];
}
}
在包含接口icCustomerEx
的程序集中,可以添加一个注册表类,该类存储icCustomerEx
的实例,如下所示
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"];
}
}
(请注意,这是一段伪代码,用于说明它是如何运行的。)
在主客户类中,您使用注册表调用其他加载
public class Customer:ICustomerEx
{
void Load(DataRow row)
{
CustomerRegistry.theRegistry.Load(row);
}
}
谢谢你的回复。我的要求和你的回答没什么不同。此客户实例需要从引用dll端创建。i、 e来自客户类存在的同一程序集中的类。我的需求是创建公共类库来创建客户实例并加载它。除此之外,当它引用任何程序集时,它还应该能够从引用的程序集加载它自己的属性。@Snj:我已经更新了我的答案,其中包含了一些关于如何执行此操作的想法。谢谢你的想法。按照您的方式,创建cust实例时,它只有“电话”成员。i、 e当我从customer类中看到它时,它只包括子类的成员。客户的成员如“姓名”、“地址”不包括在其中。
public class Customer:ICustomerEx
{
void Load(DataRow row)
{
CustomerRegistry.theRegistry.Load(row);
}
}