2012-10-18 2 views
2

구현하는 모든 인터페이스에 대해 유형을 등록 할 수 있습니까?SimpleInjector - 모든 인터페이스에 대한 유형을 등록하십시오.

public class Bow : IWeapon 
{ 

    #region IWeapon Members 

    public string Attack() 
    { 
     return "Shooted with a bow"; 
    } 

    #endregion 
} 

public class HumanFighter 

{ 
    private readonly IWeapon weapon = null; 
    public HumanFighter(IWeapon weapon) 
    { 
     this.weapon = weapon; 
    } 

    public string Fight() 
    { 

     return this.weapon.Attack(); 
    } 

} 

    [Test] 
    public void Test2b() 
    { 
     Container container = new Container(); 
     container.RegisterSingle<Bow>(); 
     container.RegisterSingle<HumanFighter>(); 

     // this would match the IWeapon to the Bow, as it 
     // is implemented by Bow 
     var humanFighter1 = container.GetInstance<HumanFighter>(); 

     string s = humanFighter1.Fight(); 
    } 

답변

1

그것은 완전히 사용자의 요구에 따라 다르지만 일반적으로는 Container의 제네릭이 아닌 등록 방법을 사용해야합니다 예컨대, 난이 있습니다. 사용자 고유의 LINQ 쿼리를 정의하여 응용 프로그램의 메타 데이터를 쿼리하여 적절한 형식을 얻고 비 제네릭 등록 메서드를 사용하여 해당 형식을 등록 할 수 있습니다. 다음은 예입니다 :

// include the SimpleInjector.Extensions namespace. 

container.RegisterManyForOpenGeneric(typeof(IValidator<>), 
    typeof(IValidator<>).Assembly); 

이 모두를 찾습니다 :

var weaponsAssembly = typeof(Bow).Assembly; 

var registrations = 
    from type in weaponsAssembly.GetExportedTypes() 
    where type.Namespace.Contains(".Weapons") 
    from service in type.GetInterfaces() 
    select new { Service = service, Implementation = type }; 

foreach (var reg in registrations) 
{ 
    container.Register(reg.Service, reg.Implementation); 
} 

당신이 필요한 경우 공유 일반적인 인터페이스를 기반으로 구현 세트를 일괄 등록, 당신은 RegisterManyForOpenGeneric 확장 방법을 사용할 수 있습니다 IValidator<T>을 구현하는 제공된 어셈블리의 (일반이 아닌) 공용 유형을 선언하고 각각을 폐쇄 일반 구현으로 등록합니다. 유형에 IValidator<T>의 여러 일반 제네릭 버전이 구현되어 있으면 모든 버전이 등록됩니다. 다음의 예를 살펴 보자 또한 편리하고 쉽게 추가 할 것

container.Register<IValidator<Customer>, MultiVal1>(); 
container.Register<IValidator<Order>, MultiVal1>(); 
container.Register<IValidator<User>, MultiVal2>(); 
container.Register<IValidator<Employee>, MultiVal2>(); 

: 지정된 인터페이스와 클래스 정의를 가정하면

interface IValidator<T> { } 
class MultiVal1 : IValidator<Customer>, IValidator<Order> { } 
class MultiVal2 : IValidator<User>, IValidator<Employee> { } 

container.RegisterManyForOpenGeneric(typeof(IValidator<>), 
    typeof(IValidator<>).Assembly); 

을, 표시된 RegisterManyForOpenGeneric 등록은 다음과 같은 수동 등록에 해당 확장 방법.

container.RegisterAsImplementedInterfaces<Sword>(); 
+0

I가 자동 배선을하고 싶으면 다음과 같이 사용할 수 있습니다

public static void RegisterAsImplementedInterfaces<TImpl>( this Container container) { foreach (var service in typeof(TImpl).GetInterfaces()) { container.Register(service, typeof(TImpl)); } } 

: 예를 들어 당신이 모든 구현 된 인터페이스에 의해 하나의 구현을 등록 할 수 있습니다 다음과 같은 확장 방법을 가지고 사용되는 구성 요소 - 리플렉션을 통해 수행 할 수 있지만 형식을 자동으로 등록하고 모든 구현 인터페이스에 대해 자동으로 연결할 수있는 것은 무엇입니까? –

+0

일괄 등록은 제네릭 형식에 대해 즉시 사용할 수 있지만 일반이 아닌 인터페이스에는 지원되지 않습니다. 이는 신중한 설계 결정입니다. 여기에 대한 자세한 내용을 볼 수 있습니다 (http://simpleinjector.codeplex.com/wikipage?title=Advanced-scenarios#Batch_Registration). 지원되지 않는 이유와 리플렉션을 사용하여이를 수행하는 방법을 알려줍니다. 이 문제가 발생하면 알려주십시오. 기꺼이 도와 드리겠습니다. – Steven

+0

리플렉션을 통해 해결했습니다. 그러나 다른 IOC 컨테이너로 할 수있는 것처럼 네이티브로 수행 할 수 있는지 알고 싶었습니다. 그렇다면 다시 큰 문제는 아니며 리플렉션을 통해 쉽게 구현할 수 있습니다. –

관련 문제