在autofacc中解析以接口作为类型参数的泛型
本文关键字:类型参数 泛型 接口 autofacc | 更新日期: 2023-09-27 18:18:56
在阅读了这里的大量文档和问题之后,我仍然被以下问题所困扰。这些是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)
执行解析调用的代码实际上是在一个ASP的Execute()方法中。. NET MVC控制器任何帮助都将非常感激!
不幸的是,您的Autofac版本有一个错误:作为泛型接口约束的泛型参数无法解析…
它已经被修复,应该在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);