2011-12-27 83 views
2

閱讀大量文檔和問題後,我仍然堅持以下幾點。這些都是與Autofac註冊的接口/實現:解決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> 
{ 
} 

登記是如下,其中Builder是一個ContainerBuilder實例,並更新了中央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):

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

如何解決可能不知道ITestService工作的實施有什麼建議?由於

_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) 

執行的決心調用的代碼實際上是在execute()方法的ASP.NET MVC控制器。

任何幫助將不勝感激!

+0

請確保你沒有一個錯字在你的configs。如果沒有錯別字,請發佈例外詳情。我已經試過你的代碼,它可以很好的與Autofac 2.5.2.830,.NET 4 – 2011-12-27 17:45:01

+0

謝謝,這很奇怪。如果這很重要,這一切都發生在一個果園CMS模塊內。這意味着我沒有意識到配置。 – Piedone 2011-12-27 17:58:06

+0

我已添加例外詳細信息。謝謝你的時間!如果它很重要,我使用的Autofac版本是2.2.4.900。 – Piedone 2011-12-27 18:08:23

回答

2

不幸的是,您的Autofac版本有一個bug: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 Team將在下一個版本中更新Autofac。 – Piedone 2011-12-27 18:37:45