I have a generic collection class based on the MvvM Light library which I've registered with Autofac:
public class DialogCollection<TViewModel> : ObservableCollection<TViewModel>, IDialogCollection<TViewModel>
{
private readonly IUIManager _uiManager;
public DialogCollection( IUIManager uiManager )
{
_uiManager = uiManager ?? throw new NullReferenceException( nameof(uiManager) );
ViewModelSelectedCommand = new RelayCommand<TViewModel>( DetailItemSelectedHandler );
AddNewViewModelCommand = new RelayCommand( AddNewItemHandler );
}
public RelayCommand<TViewModel> ViewModelSelectedCommand { get; }
public RelayCommand AddNewViewModelCommand { get; }
}
Autofac registration:
builder.RegisterGeneric( typeof(DialogCollection<>) )
.As( typeof(IDialogCollection<>) );
IUIManager, the only argument to the DialogCollection constructor, is also registered with Autofac, and is properly instantiated when the program runs.
The specific instance of IDialogCollection is generated from a lambda method created by Autofac, which is passed in thru the constructor of a class which holds an instance of the collection I want to create:
public class CommunitiesModel
{
private readonly Func<IDialogCollection<CommunityModel>> _colBuilder;
private readonly Func<CommunityModel> _communityBuilder;
private DialogCollection<CommunityModel> _communities;
public CommunitiesModel(
Func<IDialogCollection<CommunityModel>> colBuilder,
Func<CommunityModel> commmunityBuilder
)
{
_colBuilder = colBuilder ?? throw new NullReferenceException(nameof(colBuilder));
_communityBuilder= commmunityBuilder?? throw new NullReferenceException(nameof(commmunityBuilder));
}
// I'm not showing how Load() gets called, but it does :)
public override void Load()
{
// this next line creates an instance of DialogCollection
// it's also where the Autofac Missing Method exception gets thrown
Communities = (DialogCollection<CommunityModel>) _colBuilder();
}
}
Both colBuilder and communityBuilder are properly instantiated when passed into the CommunitiesModel constructor, which I presume means Autofac was able to use the registration information to create methods that create instances of those classes.
I don't understand why there's a missing method exception when _colBuilder() is executed, since the code compiles fine (meaning the RelayCommand ctor is known and available).
If I comment out the two RelayCommand creation lines (i.e., "new RelayCommand...") in the definition of DialogCollection<>, the exception is not thrown.
Which means the Autofac creator method is gacking on not finding something inside a constructor which has already been called with the appropriate constructur arguments.
Here is the exception that gets thrown:
Autofac.Core.DependencyResolutionException HResult=0x80131500
Message=An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = DialogCollection1 (ReflectionActivator), Services =[WpfFramework.IDialogCollection
1[[Olbert.CommunityScanner.Manager.ViewModel.CommunityModel, CommunityScannerManager, Version=0.0.0.1, Culture=neutral, PublicKeyToken=null]]], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope Source=Autofac StackTrace: at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters) at Autofac.Core.Resolving.InstanceLookup.Execute()
1 parameters) at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters) at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable
1 parameters) at Olbert.CommunityScanner.Manager.ViewModel.CommunitiesModel.Load() in C:\Programming\CommunityScanner\CommunityScannerManager\ViewModel\CommunitiesModel.cs:line 58 at Olbert.CommunityScanner.Manager.ViewModel.AppStateModel.set_ActivePageInfo(PageInfo value) in C:\Programming\CommunityScanner\CommunityScannerManager\ViewModel\AppWide\AppStateModel.cs:line 117 at Olbert.CommunityScanner.Manager.App.OnStartup(StartupEventArgs e) in C:\Programming\CommunityScanner\CommunityScannerManager\App.xaml.cs:line 44 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(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) in f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs:line 954
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) in f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs:line 901
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) in f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs:line 890
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 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.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at Olbert.CommunityScanner.Manager.App.Main()Inner Exception 1: DependencyResolutionException: An exception was thrown while invoking the constructor 'Void .ctor(WpfFramework.IUIManager)' on type 'DialogCollection`1'.
Inner Exception 2: MissingMethodException: Method not found: 'Void GalaSoft.MvvmLight.Command.RelayCommand
1..ctor(System.Action
1)'.
I can provide more details if needed; what I've shown here is abstracted from a larger code base, but hopefully shows the relevant details.
I would recommend looking at RelayCommand1
- it appears IUIManager
or DialogCollection<T>
needs that constructor and it's not there. Work bottom up on this. The Autofac part is red herring. Meat of the issue is the inner exception at the bottom.
User contributions licensed under CC BY-SA 3.0