[英]Autofac.Core.Registration.ComponentNotRegisteredException even the interface seems to be registered
I try to implement a WPF application using dependency injection and the MVVM pattern using the frameworks "CommunityFramework.MVVM" and "Autofac".我尝试使用依赖注入和使用框架“CommunityFramework.MVVM”和“Autofac”的 MVVM 模式来实现一个 WPF 应用程序。
What I have so far is the the following(shows only the required parts):到目前为止,我所拥有的是以下内容(仅显示必需的部分):
public class App : Application
{
private IContainer _container;
public App()
{
_builder = new ContainerBuilder();
var assembly = Assembly.GetAssembly(typeof(Installer));
string fullPath = assembly!.Location;
string dir = Path.GetDirectoryName(fullPath)!;
_builder.RegisterAssemblyModules(assembly);
var assemblyPath = Path.Combine(dir, "ViewModel.dll");
Debug.Assert(File.Exists(assemblyPath));
assembly = Assembly.LoadFile(assemblyPath);
_builder.RegisterAssemblyModules(assembly);
assemblyPath = Path.Combine(dir, "Model.dll");
Debug.Assert(File.Exists(assemblyPath));
assembly = Assembly.LoadFile(assemblyPath);
builder.RegisterAssemblyModules(assembly);
_container = _builder.Build();
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var start = _container?.Resolve<IShell<IMainWindow>>();
// HERE the Exception occcures !!!
var workSpace = _container?.Resolve<IMainWindowViewModel>();
....
}
}
public interface IShell<T> where T:class
{
// some defines here
}
public class Shell : IShell<IMainWindow>
{
public Shell()
{
// some initialization here
}
}
public class Installer : Module
{
protected override void Load(ContainerBuilder builder)
{
// Shell
object ret = builder.RegisterType<Shell>()
.As<IShell<IMainWindow>>()
.SingleInstance();
// Messanger
builder.Register(_ => MessageListener.Listen().Messenger)
.As<IMessenger>()
.SingleInstance();
}
}
public class Installer : Module
{
protected override void Load(ContainerBuilder builder)
{
// MainWindowViewModel
builder.RegisterType<MainWindowViewModel>()
.As<IMainWindowViewModel>()
. SingleInstance();
}
}
public interface IMainWindowViewModel
{
// some entries here
}
public class MainWindowViewModel : ObservableRecipient, IMainWindowViewModel
{
private IMessenger _messenger;
private IMyProjectData_data;
public MainWindowViewModel(IMyProjectDatadata, IMessenger messenger)
: base(messenger)
{
_data = data;
_messenger = messenger;
}
}
public class Installer : Module
{
protected override void Load(ContainerBuilder builder)
{
// Foto-Renamer Data
builder.RegisterType<MyProjectData>()
.As<IMyProjectData>()
.SingleInstance();
// Setings
builder.RegisterType<Settings>()
.As<ISettings>().
SingleInstance();
}
}
public interface IMyProjectData
{
// some entries here
}
public partial class MyProjectData : ObservableObject, IMyProjectData
{
private ISettings _settings;
public MyProjectData(ISettings settings)
{
_settings = settings;
// more initialization here
}
}
public interface ISettings
{
// some entries here
}
public class Settings : ISettings
{
private IShell<IWindow> _shell;
public Settings(IShell<IMainWindow> shell)
{
_shell = shell;
//more initializations here
}
}
At the marked Point i get the following exeption:在标记点我得到以下异常:
Autofac.Core.DependencyResolutionException: "An exception was thrown while activating MyProject.ViewModel.MainWindowViewModel."
Autofac.Core.DependencyResolutionException:“激活 MyProject.ViewModel.MainWindowViewModel 时抛出异常。”
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action
1 next) at Autofac.Core.Resolving.Middleware.SharingMiddleware.<>c__DisplayClass5_0.<Execute>b__0() at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func
1 creator) at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid primaryId, Nullable1 qualifyingId, Func
1 creator) at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action1 next) at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action
1 next) at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request) at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request) at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable
在 Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext 上下文,
1 next) at Autofac.Core.Resolving.Middleware.SharingMiddleware.<>c__DisplayClass5_0.<Execute>b__0() at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func
1 qualifyingId, Func
creator) 在 Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action1 next) at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action
)1 next) at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action
1)请求)在 Autofac.ResolutionExtensions.TryResolveService(IComponentContext 上下文,服务服务,IEnumerable1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable
1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable
1 parameters) at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters) at MyProject.UI.WPF.App.OnStartup(StartupEventArgs e) in F:\Projects\MyProject\UI\MyProject.UI.WPF\App.xaml.cs: Zeile64 at System.Windows.Application.<.ctor>b__1_0(Object unused) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj) at System.Threading.ExecutionContext.RunInternal(1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable
1 参数)在 Autofac.ResolutionExtensions.Resolve[TService](IComponentContext 上下文,IEnumerable`1 参数)在 MyProject.UI.WPF.App.OnStartup(StartupEventArgs e ) 在 F:\Projects\MyProject\UI\MyProject.UI.WPF\App.xaml.cs: Zeile64 at System.Windows.Application.<.ctor>b__1_0(Object unused) at System.Windows.Threading.ExceptionWrapper.InternalRealCall (Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System .Windows.Threading.DispatcherOperation.InvokeInSecurityContext(对象状态)在 MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(对象对象)在 System.Threading.ExecutionContext.RunInternal( ExecutionContext executionContext, ContextCallback callback, Object state)ExecutionContext executionContext,ContextCallback回调,Object状态)
Autofac.Core.DependencyResolutionException: "None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyProject.ViewModel.MainWindowViewModel' can be invoked with the available services and parameters: Cannot resolve parameter 'MyProject.Model.Interfaces.IMyProjectData data' of constructor 'Void.ctor(MyProject.Model.Interfaces.IMyProjectData, CommunityToolkit.Mvvm.Messaging.IMessenger)'."
Autofac.Core.DependencyResolutionException:“在类型‘MyProject.ViewModel.MainWindowViewModel’上使用‘Autofac.Core.Activators.Reflection.DefaultConstructorFinder’找到的构造函数都不能用可用的服务和参数调用:无法解析参数‘MyProject.Model .Interfaces.IMyProjectData 数据'构造函数'Void.ctor(MyProject.Model.Interfaces.IMyProjectData, CommunityToolkit.Mvvm.Messaging.IMessenger)'。”
at Autofac.Core.Activators.Reflection.ReflectionActivator.<>c__DisplayClass12_0.b__0(ResolveRequestContext ctxt, Action
1 next) at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action
1 next) at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)在 Autofac.Core.Activators.Reflection.ReflectionActivator.<>c__DisplayClass12_0.b__0(ResolveRequestContext ctxt,
1 next) at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action
1) .Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext 上下文,下一个 Action`1)
I checked that all three "Installer"-classes are reached and the registration is executed properly.我检查了所有三个“安装程序”类都已达到并且注册已正确执行。 At the point of the exception I tryed the container: All servicec can be resolved, expected:
在异常点我尝试了容器:所有servicec都可以解决,预期:
_container.Resolve<IMyProjectData>()
and_container.Resolve<IMyProjectData>()
和
_container.Resolve<ISettings>()
(this is required as parameter for IMyProjectData.ctor)_container.Resolve<ISettings>()
(这是 IMyProjectData.ctor 的必需参数)
Can anybody see why the exception raises?任何人都可以看到为什么会引发异常吗? It seems I'm blind for the moment.
看来我暂时瞎了。 Thank you in advance for your response.
预先感谢您的回复。
The problem is that you have 2 instances of FotoRenamer.Model.dll loaded.问题是您加载了 2 个 FotoRenamer.Model.dll 实例。
If you set a breakpoint on the faulting line and then open Debug->Windows->Modules
you will see it.如果您在故障线上设置断点,然后打开
Debug->Windows->Modules
,您将看到它。 It's caused by loading the assemblies with Assembly.LoadFile()
.这是由使用
Assembly.LoadFile()
加载程序集引起的。 The assemblies loaded this way are loaded into different load context (see https://learn.microsoft.com/en-us/do.net/framework/deployment/best-practices-for-assembly-loading?source=recommendations for details about load contexts).以这种方式加载的程序集被加载到不同的加载上下文中(有关详细信息,请参阅https://learn.microsoft.com/en-us/do.net/framework/deployment/best-practices-for-assembly-loading?source=recommendations关于加载上下文)。
Since all assemblies are referenced by the main project you don't need to load them.由于所有程序集都被主项目引用,因此您无需加载它们。 The fix is simple:
修复很简单:
public static void InstallAutofac(ContainerBuilder builder)
{
var assembly = Assembly.GetAssembly(typeof(Installer));
builder.RegisterAssemblyModules(assembly);
assembly = Assembly.GetAssembly(typeof(ViewModel.Installer));
builder.RegisterAssemblyModules(assembly);
assembly = Assembly.GetAssembly(typeof(Model.Installer));
builder.RegisterAssemblyModules(assembly);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.