이것은 매우 복잡한 요구 사항이며 이것을 해결하기 위해 여러 가지 패턴 &을 모아야합니다. 내가 따라 가면서 관련 원칙을 시도해 보도록하겠습니다.
첫 번째 문제는 두 클래스 라이브러리가 공통 인터페이스를 갖도록 정렬하는 것입니다. 이는 설명대로 상호 교환 할 수 있도록하기 위해 필요합니다. 일반적으로 두 객체가 구현하는 인터페이스를 만드는 것만 큼 간단 할 것입니다. 그러나 라이브러리 중 하나를 제어 할 수 있다고 언급했습니다. 이 경우 adapter pattern을 사용하여 공용 인터페이스를 구현할 수없는 라이브러리를 강제 변환해야합니다.
는
// in Library1.dll
public class Foo
{
public int DoSomething() { ... }
}
// In Library2.dll
public class Foo
{
public int DoSomething() { ... }
}
먼저 우리는 우리의 공통 인터페이스를 정의 할 필요가 ... 우리가 현재 Library1.dll
및 Library2.dll
(Library1.dll 우리가 제어 할 수있는 하나)이 두 클래스를 말해봐. 이것은 ... 우리가 도서관 하나를 제어 할 수 있기 때문에, 우리는 쉽게이 일반적인 방법으로 공통의 인터페이스를 구현 할 수 있습니다 ... 지금 핵심/공유 라이브러리에
// In Shared.dll
public interface IFoo
{
int DoSomething();
}
을 있어야합니다
// In Library1.dll
public class Foo : IFoo
{
public int DoSomething() { ... }
}
Library2.dll
을 제어 할 수 없기 때문에 어댑터 클래스를 만들어야합니다. 이 클래스의 목적은 공통 인터페이스를 구현하는 것이며 모든 동작은 Library2.Foo
실제로 위임됩니다. 결과적으로 이것은 Library2.Foo
객체가 우리의 공용 인터페이스를 구현하도록합니다.
// In Shared.dll
public class Foo2Adapter : IFoo()
{
private Library2.Foo _realFoo;
public Foo2Adapter()
{
_realFoo= new Library2.Foo();
}
public int DoSomething()
{
_realFoo.DoSomething();
}
}
이제 개체 대신 직접 공용 인터페이스를 사용하도록 모든 클라이언트 코드를 수정해야합니다. 당신이
namespace Project
{
public class MyClass
{
public void Bar(IFoo foo)
{
foo.DoSomething();
}
}
}
이제 우리는 새로운 문제가 ...
if(arg == "a")
using LibraryA;
if(arg == "b")
using LibraryB;
namespace Project
{
public class MyClass
{
public void Bar()
{
var foo = new Foo();
foo.DoSomething();
}
}
}
지금 코드는 인터페이스를 사용한다 ... 이런 일이 있었다 수도 이전에 어디에서, 어떻게 우리가 버전을 알 수 있습니까 사용하는
IFoo
?
Library1.Foo
또는
Shared.Foo2Wrapper
입니까?
dependency injection을 사용하면이 문제를 해결할 수 있습니다. 컨트롤 컨테이너를 반전하면 개체가 제공되며 특정 조건에 따라 여러 종류의 개체를 제공하도록 개체를 구성 할 수 있습니다. 다음은 StructureMap (내 개인적으로 좋아하는 IoC 컨테이너)에서 사용되는 것과 유사한 sytax를 사용하는 psuedocode 예제입니다.
var container = new IocContainer();
if (arg == "a")
container.For<IFoo>().Use<Library1.Foo>();
else if (arg == "b")
container.For<IFoo>().Use<Shared.Foo2Adapter>();
var foo = container.GetInstance<IFoo>();
이제 우리는 IoC 컨테이너가 다시 우리를 줄 것이다 GetInstance<IFoo>()
를 호출 할 때 중 하나 Library1.Foo
또는 명령 행에 의해 구성 방식에 따라 Shared.Foo2Wrapper
. 이제 클라이언트 코드에서 이전에 new Foo()
이있는 모든 위치를 거쳐 container.GetInstance<IFoo>()
으로 바꿔야합니다.
나는 당신을 움직일 수 있기를 바랍니다. :)
왜이 기능이 필요합니까? 왜 둘 다 참조하지 않습니까? –
매우 까다 롭습니다. 나중에 두 개의 라이브러리를 참조하십시오. 나중에 인수를 기준으로 사용합니다. – andy
인터페이스가 아닌 코드의 구체적인 유형을 언급하는 경우 컴파일시 특정 유형 또는 변수가 고정됩니다. 이 라이브러리들 사이에 공통점이 있습니까 (아마도 네임 스페이스와 유형 이름 제외)? –