2011-12-27 3 views
2

여기에서 많은 설명서와 질문을 읽은 후에도 여전히 다음과 같은 문제가 있습니다. 이러한 인터페이스/Autofac에 등록 구현입니다 : 등록 빌더는 ContainerBuilder의 인스턴스 인 경우에, 다음과 같습니다Autofac에서 인터페이스 매개 변수로 제네릭을 해결하십시오.

public interface ITestService<T> 
{ 
} 

public class TestService<T> : ITestService<T> 
{ 
} 

public interface ITest<TService, T> 
    where TService : ITestService<T> 
{ 
} 

public class Test<TService, T> : ITest<TService, T> 
    where TService : ITestService<T> 
{ 
} 

과 중앙 IComponentRegistry 업데이트 :

builder.RegisterGeneric(typeof(TestService<>)).As(typeof(ITestService<>)).InstancePerLifetimeScope(); 

builder.RegisterGeneric(typeof(Test<,>)).As(typeof(ITest<,>)).InstancePerLifetimeScope(); 

지금이 작동을 (_componentContext는 IComponentContext 인스턴스입니다.

_componentContext.Resolve<ITest<TestService<MyType>, MyType>>(); 

(ComponentNotRegisteredException을 던지는)하지 않습니다 해결이 ITestService의 구현을 모르고 일할 수있는 방법에 대한

_componentContext.Resolve<ITest<ITestService<TNodeToNodeConnectorRecord>, TNodeToNodeConnectorRecord>>(); 

모든 팁?

_componentContext.Resolve<ITestService<MyType>>(); 

예상대로 작동합니다. 유형을 사용하면 어떻게 든 사용할 수 있지만 성공하지 못했습니다.

업데이트, 예외 사항 :

"The requested service 'MyProject.ITest`2[[MyProject.ITestService`1[[MyProject.MyType, MyProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], MyProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[MyProject.MyType, MyProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]' has not been registered." 

스택 추적 :

at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Service service, IEnumerable`1 parameters) 
    at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters) 
    at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters) 
    at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context) 
    at MyProject.SomeController`4.Execute(RequestContext requestContext) in d:\SomeController.cs:line 55 
    at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) 
    at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5() 
    at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
    at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End() 
    at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d() 
    at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) 
    at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) 
    at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) 
    at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) 
    at Orchard.Mvc.Routes.ShellRoute.HttpAsyncHandler.EndProcessRequest(IAsyncResult result) in D:\MyProject.SomeRoutes.cs:line 148 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

결의 호출을 실행하는 코드가 실행() 메소드에 실제로 던져진 예외는 다음과 같습니다 ASP.NET MVC 컨트롤러의.

도움이 될 것입니다.

+0

하십시오, 당신은 당신의 CONFIGS에 오타가없는 있는지 확인합니다. 오타가없는 경우 예외 세부 정보를 게시하십시오. 귀하의 코드를 시도했는데 Autofac 2.5.2.830, .NET 4 –

+0

으로 잘 작동합니다. 고맙습니다. 이상합니다. 이것이 중요한 경우, Orchard CMS 모듈 내부에서 일어납니다. 즉, 내가 알고있는 구성이 없음을 의미합니다. – Piedone

+0

예외 세부 정보를 추가했습니다. 시간 내 줘서 고마워! 중요한 경우 Autofac 버전은 2.2.4.900입니다. – Piedone

답변

2

아쉽게도 Autofac 버전에 Generic parameters constrained as generic interfaces fail to resolve. 버그가 있습니다.

2.5.1에서 수정되었습니다. 이 기능을 사용하려면 업그레이드해야합니다.

또는 당신은 해결 시도 할 수 있습니다 :

public interface ITestService<T> 
{ 
} 

public class TestService<T> : ITestService<T> 
{ 
} 

public interface ITest<T> 
{ 
    ITestService<T> TestService { get; } 
} 

public class Test<T> : ITest<T> 
{ 
    readonly ITestService<T> _TestService; 

    public Test(ITestService<T> testService) 
    { 
    _TestService = testService; 
    } 

    public ITestService<T> 
    { 
    get 
    { 
     return this._TestService; 
    } 
    } 
} 

builder.RegisterGeneric(typeof(TestService<>)).As(typeof(ITestService<>)).InstancePerLifetimeScope(); 
builder.RegisterGeneric(typeof(Test<>)).As(typeof(ITest<>)).InstancePerLifetimeScope(); 
... 

_componentContext.Resolve<ITest<TNodeToNodeConnectorRecord>>(); 

// if you need to specify the ITestService type to use: 
var testService = _componentContext.Resolve<TestService<TNodeToNodeConnectorRecord>>(); 
var test = _componentContext.Resolve<Func<ITestService<TNodeToNodeConnectorRecord>, ITest<TNodeToNodeConnectorRecord>>>()(testService); 
+0

고마워, 훌륭해! Orchard 팀이 다음 릴리스에서 Autofac을 업데이트 할 것입니다. – Piedone

관련 문제