2010-01-13 3 views
1

StructureMap을 사용하여 공개 제네릭 유형에 setter injection을 사용하려고합니다. 내가 푸의 상속자의 "바"를 해결하기 위해 세터 주입을 사용하려는개방형 제네릭 유형의 StructureMap setter 주입?

public abstract class Foo<T1, T2> : IMyInterface<T1,T2> 
{ 
    public ISomeDependency Bar { get; set; } 
} 

:

나는 추상 제네릭 클래스가 있습니다. 막대의 [SetterDependency] 특성을 사용하여이 작업을 수행 할 수 있지만 해당 클래스를 꾸미지 않으려합니다. .

내가 그렇게처럼 DSL에 ForConcreteType를 사용할 수 있다고 생각했던 :

ForConcreteType (대해서 typeof (푸 <,>)) Configure.Setter() IsTheDefault();.

하지만 ForConcreteType은 일반적인 구현만을 가지고 있습니다.

I는 다음과 같이 구성에서이 작업을 수행하는 것을 시도했다 :

이 컴파일 있지만 해결하려고 시도 할 때 "연결 할 수없는 타입으로"런타임 예외가 발생
For(typeof (Foo<,>)) 
.Use(typeof (Foo<,>)).SetterDependency<ISomeDependency>("Bar").IsAutoFilled(); 

.

누구나이 경우 설정 기 주입을 수행하는 방법을 알고 있습니까? 감사!

편집 :

[Test] 
public void can_resolve_open_generic_type_using_setter_injection() 
{ 
    ObjectFactory.Initialize(x => 
           { 
x.For<ISession>().Use<DatabaseSession>(); 
// uncomment next line and it resolves: 
// x.SetAllProperties(set => set.OfType<ISession>()); 
x.ForRequestedType<IHandler<OrderReceivedMessage>>() 
.TheDefaultIsConcreteType<OrderHandler>(); 

           }); 

    var instance = ObjectFactory.Container.GetInstance<IHandler<OrderReceivedMessage>>(); 

    instance.ShouldBeOfType<DatabaseTransactionHandler<OrderReceivedMessage>>(); 
    instance.ShouldBeOfType<OrderHandler>(); 

    var asTransactionHandler = (DatabaseTransactionHandler)instance; 
    Assert.IsNotNull(asTransactionHandler.Session); 

} 

public interface IHandler<TMessage> 
{ 
    void Handle(TMessage message); 
} 

public abstract class DatabaseTransactionHandler<TMessage> : IHandler<TMessage> 
{ 

    // need to inject this with the default ISession 
    // works when using [SetterDependency] attribute 
    public ISession Session { get; set; } 

    public abstract void DoHandle(TMessage message); 

    public virtual void Handle(TMessage message) 
    { 
      using (ITransaction transaction = Session.CreateTransaction()) 
      { 
       try 
       { 
        DoHandle(message); 
        transaction.Commit(); 
       } 
       catch (Exception handlerException) 
       { 
        transaction.Rollback(); 
        throw; 
       }     
      } 
    } 
} 


public class OrderHandler : DatabaseTransactionHandler<OrderReceivedMessage> 
{ 
    public override void DoHandle(OrderReceivedMessage message) 
    { 
     Order order = CreateOrderFromMessage(message); 
     Session.Save(order); 
    } 
} 

답변

1

난 당신이 IMyInterface에 의해 푸를 검색한다고 가정 -되지 않은 푸 요청에 의해 : 요청으로

, 여기에 내가 달성하기 위해 노력하고있어의 정교한 예입니다. 그래서 For (typeof (IMyInterface <,>))를 원할 것입니다. 이 코드는 (트렁크 소스 코드를 사용하여) 나를 위해 작동 : 형 ISomeDependency의 속성을 가지고있는 컨테이너에서 검색 한 모든 유형 채워 않도록 또는

var container = new Container(x => 
{ 
    x.For<ISomeDependency>().Use<TheDependency>(); 
    x.For(typeof (IMyInterface<,>)).Use(typeof (Foo<,>)).SetterDependency<ISomeDependency>("Bar").IsAutoFilled(); 
}); 

var instance = (Foo<string, bool>)container.GetInstance(typeof (IMyInterface<string, bool>)); 
Console.WriteLine(instance.Bar.GetType().Name); 

을, 당신은 규칙을 설정할 수 있습니다 :

var container = new Container(x => 
{ 
    x.For<ISomeDependency>().Use<TheDependency>(); 
    x.For(typeof (IMyInterface<,>)).Use(typeof (Foo<,>)); 
    x.SetAllProperties(set => set.OfType<ISomeDependency>()); 
}); 

당신은 사실, 푸 요청에 의해 푸를 검색하려고 x.SetAllProperties를 사용하여 다른 기준 (설정 => set.Matching (...))

+0

에 규칙을도를 기반으로 할 수 있습니다. ForRecestedType, ForRequestedType 및 TheDefault.Is 메서드에 동일한 구체 형식을 전달하는 기능을 근사하려고합니다. Foo 은 추상적이기 때문입니다. 실제로 제네릭 형식을 기반으로 IFoo 콘크리트를 해결하고 있습니다. 그 구체적인 유형이 추상 기본 유형 Foo 에서 상속을받는다면 Bar 속성에 기본 ISomeDependency를 주입하려고합니다. 이것은 "개방형 제네릭 유형"문제입니다. SetAllProperties 해결 방법에 대해 투표 해 드리겠습니다. 감사! – pfries

+0

좋아, 내가 가정하지 말았어야 겠어. 때로는 예제를 따라하기가 어려워지며 모든 IFoo와 IMyInterface가 이름의 산만 함을 나타냅니다 (귀하의 의견은 귀하의 원래 게시물이하지 않은 IFoo를 언급합니다). 귀하의 문제를 보여주는 완전한 NUnit 테스트를 게시 할 수 있습니까? 작성된 클래스와 인터페이스를 사용할 수 있으며, 완전한 정의가 포함되어 있는지 확인하십시오. –

+0

모든 Foo에 대해 죄송합니다. 나는 그것이 물건을 혼란 시킨다는 데 동의한다. 내가 더 자세히하려고하는 것을 설명하기 위해 편집을 게시했습니다. 보시다시피 IHandler 이 기본 유형이고 DatabaseTransactionHandler 은 Session : Session 속성이있는 추상 클래스입니다.세션은 DatabaseTransactionHandler 의 상속자가 데이터베이스 세션에 액세스하는 데 사용됩니다. 이 속성을 [SetterDependency] 특성으로 꾸미지 않고 삽입하거나 전역 SetAllProperties 메서드를 사용하여 삽입하려고합니다. 모든 도움에 감사드립니다! – pfries

관련 문제