我很难理解为什么我似乎无法使用autofac 3.5.2(也尝试使用4.4版)来使用Web Api 2.2 + Owin。
我的控制器需要IClass1
的依赖关系。它似乎已注册,但由于某种原因,它无法在运行时解决。知道问题可能是什么吗?
有问题的注册似乎在那里(请参阅第4行 - Class1
注册为IClass1
):
并且生命周期范围是正确的,它被设置为:AutofacWebRequest
public void Configuration(IAppBuilder app)
{
var suffix = typeof(DefaultHttpControllerSelector).GetField("ControllerSuffix", BindingFlags.Static | BindingFlags.Public);
if (suffix != null) suffix.SetValue(null, string.Empty);
var container = InitializeDiContainer(app);
var config = new HttpConfiguration
{
DependencyResolver = new AutofacWebApiDependencyResolver(container)
};
config.MapHttpAttributeRoutes();
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
Mapper.Initialize(cfg =>
{
foreach (var profile in container.Resolve<IEnumerable<Profile>>())
{
cfg.AddProfile(profile);
}
});
OnEndpointConfigurationCompleted(app, container);
}
private IContainer InitializeDiContainer(IAppBuilder app)
{
var builder = new ContainerBuilder();
var allAssemblies = AssemblyUtils.GetAllAssemblies();
builder.RegisterApiControllers("Endpoint", AssemblyUtils.GetEndpointAssemblies());
builder.RegisterAssemblyTypes(AssemblyUtils.GetAllAssemblies())
.Where(t => typeof(IReadModelService).IsAssignableFrom(t) ||
typeof(IRepository).IsAssignableFrom(t))
.AsImplementedInterfaces()
.InstancePerRequest()
.PropertiesAutowired();
builder.RegisterAssemblyTypes(AssemblyUtils.GetAllAssemblies())
.Where(t => typeof(IProvider).IsAssignableFrom(t))
.AsImplementedInterfaces()
.InstancePerRequest()
.PropertiesAutowired();
var configFilePath = Path.Combine(HttpRuntime.BinDirectory, "endpointConfig.json");
builder.Register(ctx => JsonConvert.DeserializeObject<Class1Setting>(File.ReadAllText(configFilePath)))
.InstancePerRequest();
return builder.Build();
}
public class Class1 : IClass1
{ }
public interface IClass1 : IReadModelService
{ }
public class Class1Setting
{
public string DataSource { get; set; }
}
控制器无法解析IClass1
实例。
public class DeviceQueriesEndpoint : ApiController, IDeviceQueriesEndpoint
{
private IClass1 _class1;
public DeviceQueriesEndpoint(IClass1 class1)
{
_class1 = class1;
}
}
这是我在运行时获得的异常:
尝试创建“DeviceQueriesEndpoint”类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。
Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
An error occurred when trying to create a controller of type 'DeviceQueriesEndpoint'. Make sure that the controller has a parameterless public constructor.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = DeviceQueriesEndpoint (DelegateActivator), Services = [xpto.Middleware.Api.Device.Endpoint.DeviceQueriesEndpoint], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = ExternallyOwned ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = DeviceQueriesEndpoint (ReflectionActivator), Services = [xpto.Middleware.Api.Device.Endpoint.DeviceQueriesEndpoint], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xpto.Middleware.Api.Device.Endpoint.DeviceQueriesEndpoint' can be invoked with the available services and parameters: Cannot resolve parameter 'xpto.ClassLibrary1.IClass1 class1' of constructor 'Void .ctor(xpto.ClassLibrary1.IClass1)'. (See inner exception for details.) (See inner exception for details.)
</ExceptionMessage>
<ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType>
<StackTrace>
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.Execute() at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters) at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType) at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = DeviceQueriesEndpoint (ReflectionActivator), Services = [xpto.Middleware.Api.Device.Endpoint.DeviceQueriesEndpoint], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xpto.Middleware.Api.Device.Endpoint.DeviceQueriesEndpoint' can be invoked with the available services and parameters: Cannot resolve parameter 'xpto.ClassLibrary1.IClass1 class1' of constructor 'Void .ctor(xpto.ClassLibrary1.IClass1)'. (See inner exception for details.)
</ExceptionMessage>
<ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType>
<StackTrace>
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.Execute() at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Registration.ExternalRegistrySource.<>c__DisplayClass2_0.<RegistrationsFor>b__2(IComponentContext c, IEnumerable`1 p) at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xpto.Middleware.Api.Device.Endpoint.DeviceQueriesEndpoint' can be invoked with the available services and parameters: Cannot resolve parameter 'xpto.ClassLibrary1.IClass1 class1' of constructor 'Void .ctor(xpto.ClassLibrary1.IClass1)'.
</ExceptionMessage>
<ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType>
<StackTrace>
at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters) at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
</StackTrace>
</InnerException>
</InnerException>
</InnerException>
</Error>
如果我手动注册它的具体类型,这是奇怪的:
builder.RegisterType<Class1>().As<IClass1>();
如果我删除构造函数并手动尝试在操作中解析IClass1
,它仍然会失败,这让我相信我正在使用的堆栈组合存在某种错误。
答案 0 :(得分:0)
实际上这与Autofac无关。我使用的是Assembly.LoadFile,它没有考虑到程序集绑定。