2013-07-06 3 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 이 클래스에는 자신의 속성이 있으며 해당 load 메서드에서 해당 속성을로드합니다.

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

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

지금은 의존성 삽입 (Dependency Injection)처럼 사용하여 자신의 특성을의로드 한 후 UI 프로젝트의 속성을로드하는 Load 메서드 내 첫 번째 클래스의 (클래스 라이브러리로 그 빌드)를 구현할 수있는 방법이있다.

예 :

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 개체의 목록을 각 고객에게 종속성을 주입해야합니다. 그런 다음 관련 속성의 하위 집합 만 포함하는 서로 다른 개체로 이루어집니다. . 그것은 상속 + 더 적합 할 수있는 템플릿 메소드 패턴 같은 소리 :

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 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
: 또는

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

을, 당신은 공장 패턴을 사용할 수 있습니다

이 다른 구현을 호출 할 수 있습니다

ICustomerEx 인터페이스를 포함하는 어셈블리에서 레지스트리를 추가 할 수 있습니다 이

처럼 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); 
} 
} 
관련 문제