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);
 }
}