gpt4 book ai didi

c# - Autofac 无法在运行时解析来自某些程序集的类型,在调试器中工作

转载 作者:太空宇宙 更新时间:2023-11-03 12:34:38 25 4
gpt4 key购买 nike

在我的解决方案中,我有更多的程序集。其中一些包含一个 Autofac 模块,其中包含来自程序集的注册。我在启动后立即将所有注册连接在一起。到目前为止一切正常,我通过构造函数注入(inject)创建了依赖项,Autofac 帮助我解决了依赖项。

(在这个项目中,我在控制台应用程序中托管 SignalR 和 WebApi 功能。我也使用 OWIN。)

在添加 WebApi 并使用 DI 创建我的第一个 Controller 后,我遇到了一个问题。在 MyController 的构造函数中我依赖 MyInterface .当我尝试在我的 Controller 上调用任何方法时,我得到了普通的

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyController' can be invoked with the available services and parameters: Cannot resolve parameter 'MyInterface myInt' of constructor 'Void .ctor(MyInterface)'.

异常。我注意到了什么:

  • 如果我替换MyInterface与另一个组件中的另一个一起加载 Controller 。
  • MyInterface可以在我的代码中的另一个地方解决(在另一个程序集中)

我继续进行一些调试。我试图在我的 OWIN 启动类中的启动时解决一些类。我现在看到的是

  • 我无法解析 MyAssembly1 中的任何类型, MyAssembly2
  • 我可以解析 MyAssembly3 中的所有类型, MyAssembly4
  • container.Resolve<MyInterface> 从代码中抛出异常
  • container.Resolve<MyInterface>如果我在调试期间通过 Visual Studio 中的监 window 口解析它,则返回已解析的类
  • 我在container.ComponentRegistry.Registrations 中看到所有 注册

你能告诉我,我做错了什么吗?

更新

我尽量提供所有必要的信息,请让我知道,如果我仍然忘记了什么。

这是 AssemblyA 中的 Autofac 模块定义

public class AutofacModuleConfig : Module, IAutofacModuleConfig
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyWorkingImplementation>().As<IMyWorkingInterface>();

base.Load(builder);
}

这是 AssemblyB 中的 Autofac 模块定义

public class AutofacModuleConfig : Module, IAutofacModuleConfig
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyNotWorkingImplementation>().As<IMyNotWorkingInterface>();

base.Load(builder);
}
}

在设置 WebHost 的程序集中有 Controller 的注册(与以前的结构相同)

builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

这就是我在应用程序启动时注册东西的方式

private void RegisterModuleDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterType<Core.Logger.Log4NetLogger>().As<ILogger>();

var moduleConfigs = GetModuleConfigurations();
foreach (var module in moduleConfigs)
builder.RegisterModule(module);

container = builder.Build();
}

private List<Autofac.Module> GetModuleConfigurations()
{
var type = typeof(IAutofacModuleConfig);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && p.GetConstructor(Type.EmptyTypes) != null);
return types.Select(t => (Autofac.Module)Activator.CreateInstance(t)).ToList();
}

这是SignalR和WebApi的启动方法

private void Startup(IAppBuilder app)
{
IDependencyResolver resolver = new AutofacDependencyResolver(container);
GlobalHost.DependencyResolver = resolver;

...

ConfigureOAuth(app, resolver.Resolve<IAuthorizationService>());

app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(new HubConfiguration
{
Resolver = resolver,
EnableDetailedErrors = true,
EnableJavaScriptProxies = false
});

//Host WebApi
HttpConfiguration webApiConfiguration = new HttpConfiguration();
webApiConfiguration.MapHttpAttributeRoutes();
webApiConfiguration.Routes.MapHttpRoute("DefaultWebApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });
webApiConfiguration.Services.Add(typeof(System.Web.Http.ExceptionHandling.IExceptionLogger), new WebApiExceptionLogger());
webApiConfiguration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
app.UseWebApi(webApiConfiguration);
}

出于测试目的,我包含了常见示例中使用的 ValuesController。使用默认构造函数,它自然可以正常工作。如果我用 IMyWorkingInterface 添加构造函数然后,正如其名称所暗示的那样,它可以完美运行。但是,如果我将构造函数包含在 IMyNotWorkingInterface 中而不是工作的然后我得到了异常。

public class ValuesController : ApiController
{
//private readonly TestNamespaceInAssemblyB.IMyNotWorkingInterface notWorkingInstance;

//public ValuesController(TestNamespaceInAssemblyB.IMyNotWorkingInterface notWorkingInstance)
//{
// this.notWorkingInstance = notWorkingInstance;
//}

private readonly TestNamespaceInAssemblyA.IMyWorkingInterface workingInstance;

public ValuesController(TestNamespaceInAssemblyA.IMyWorkingInterface workingInstance)
{
this.workingInstance = workingInstance;
}

想在加IMyNotWorkingInterface的时候再点一下作为另一个程序集(比方说 AssemblyC)的依赖项,然后它会被 Autofac 正确解析。

在调试器中我看到了注册 MyNotWorkingImplementation在监 window 口中。更重要的是,我什至可以从调试器中解决它,正如您在图像上看到的那样。

enter image description here

更新2

我为 Autofac 事件创建了事件处理程序,这里的日志显示了当我尝试注入(inject) IMyNotWorkingInterface 时发生的情况。

2017-01-08 13:32:36.920753 | [0x00002acc] | DEBUG | Core        - WebHost                                   | AGENT  | Chile lifetime scope started
2017-01-08 13:32:36.934754 | [0x00002acc] | DEBUG | Core - WebHost | AGENT | Resolve operation started
2017-01-08 13:32:36.936754 | [0x00002acc] | DEBUG | Core - WebHost | AGENT | Instance lookup is beginning for Activator = ValuesController (DelegateActivator), Services = [API.Agent.Web.Controllers.ValuesController], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = ExternallyOwned
2017-01-08 13:32:36.938754 | [0x00002acc] | DEBUG | Core - WebHost | AGENT | Instance lookup is beginning for Activator = ValuesController (ReflectionActivator), Services = [API.Agent.Web.Controllers.ValuesController], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope
2017-01-08 13:32:36.939754 | [0x00002acc] | DEBUG | Core - AutofacModuleConfig | AGENT | Resolve for was requested by Activator = ValuesController (ReflectionActivator), Services = [API.Agent.Web.Controllers.ValuesController], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope
2017-01-08 13:32:36.966757 | [0x00002acc] | DEBUG | Core - WebHost | AGENT | Resolve operation finished
2017-01-08 13:32:36.967757 | [0x00002acc] | ERROR | Core - WebHost | AGENT |
Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'API.Agent.Web.Controllers.ValuesController' can be invoked with the available services and parameters:
Cannot resolve parameter 'TestNamespaceInAssemblyB.IMyNotWorkingInterface notWorkingInstance' of constructor 'Void .ctor(TestNamespaceInAssemblyB.IMyNotWorkingInterface)'.
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
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__DisplayClass8.<RegistrationsFor>b__3(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)
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)
2017-01-08 13:32:38.085869 | [0x000029c4] | DEBUG | Core - WebHost | AGENT | Child lifetime scope closed

知道在哪里可以将一些调试代码粘贴到 Autofac 中吗? (对了,我用的是Autofac 3.5.2)

最佳答案

确保注册您的 Controller 。您需要为 autofac 包含 WebApi 特定的 nuget 包,并在启动时从您的容器构建器调用以下方法:

RegisterApiControllers(Assembly.GetExecutingAssembly());

关于c# - Autofac 无法在运行时解析来自某些程序集的类型,在调试器中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41505364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com