Simple Injector에서이를 해결할 수있는 몇 가지 방법이 있습니다.
우선, 항상 구성 요소에 단일 생성자가 있습니다 (multiple constructors is an anti-pattern).
그러나 제공된 유형은 외부 라이브러리에서 가져온 것이므로 변경할 수 없습니다.
대신 할 수있는 것은이 특정 유형에서 파생되며 하나의 생성자 만 가진 하위 클래스를 만드는 것입니다. 이것은이기 때문에, 당신은 응용 프로그램에서 정의되지 않은 추상화에 의존하는 응용 프로그램 코드를 필요가 없도록해야한다, 그러나 일반적으로
class MyBaseClassManager<T> : BaseCacheManager<T>
{
public MyBaseClassManager([args]) : base([args]) { }
}
container.RegisterSingleton(typeof(ICacheManager<>), typeof(MyBaseCacheManager<>)):
:이 유형은 관심있는 기본 클래스의 특정 생성자로 호출 할 수 있습니다 Dependency Inversion Principle (DIP) 위반. DIP은 애플리케이션 맞춤형 추상화를 정의합니다. 이러한 추상화에 따라 외부 구성 요소로 호출을 전달하는 어댑터를 정의 할 수 있습니다. 예 : here를 설명한 바와 같이,
container.RegisterSingleton<ICacheManager<Foo>>(new BaseCacheManager<Foo>());
container.RegisterSingleton<ICacheManager<Bar>>(new BaseCacheManager<Bar>());
container.RegisterSingleton<ICacheManager<FooBar>>(new BaseCacheManager<FooBar>());
는 또 다른 옵션은 생성자 해상도 동작을 재정의하는 것입니다 : 당신이 필요로하는 폐쇄 유형의 수에 제한이있는 경우
이
// In the application's core layer
public interface ICache<T>
{
}
// Adapter in the Composition Root
public sealed class CacheManagerCacheAdapter<T> : ICache<T>
{
private static BaseCacheManager<T> manager = new BaseCacheManager<T>();
// Implement ICache<T> methods
public object GetByKey(object key)
{
// translate and forward to the external component
return this.manager[key];
}
}
// Registration
container.RegisterSingleton(typeof(ICache<>), typeof(CacheManagerCacheAdapter<>)):
, 당신은 명시 적으로 모든 폐쇄 된 버전을 등록 할 수 있습니다. 이
public class CacheManagerConstructorResolutionBehavior
: IConstructorResolutionBehavior {
private readonly IConstructorResolutionBehavior org;
public CacheManagerConstructorResolutionBehavior(IConstructorResolutionBehavior org) {
this.org = org;
}
public ConstructorInfo GetConstructor(Type serviceType, Type implementationType) {
if (implementationType.IsGenericType &&
implementationType.GetGenericTypeDefinition() == typeof(BaseCacheManager<>)) {
return implementationType.GetConstructors()
.OrderByDescending(c => c.GetParameters().Length)
.First();
}
return this.org.GetConstructor(serviceType, implementationType);
}
}
var container = new Container();
container.Options.ConstructorResolutionBehavior =
new CacheManagerConstructorResolutionBehavior(
container.Options.ConstructorResolutionBehavior);
는 또 다른 옵션은 내가에만이 같은 최후의 수단을 권합니다 있지만 ResolveUnregisteredType` event 사이에 끼어하는 것입니다 수 있습니다.
유형에 생성자가 하나만 있는지 확인해야합니다. 다른 생성자를 제거하십시오. – Steven
답장을 보내 주신 Steve에게 감사드립니다. 캐싱을 돕기 위해 CacheManager.net의 외부 라이브러리를 사용하고 있습니다. 두 번째 생성자를 제거하는 것 외에는 다른 대안이 있습니까? –
DI 프레임 워크를 사용할 수 없습니까? 심지어 새로운 경량의 MS (dotnet core)도 처리 할 수 있습니다. 클래스에 대해 단 하나의 공용 ctor를 허용하는 것은 매우 큰 제한입니다. ~~ – MichaC