Autofac没有用参数击中构造函数

Posted

技术标签:

【中文标题】Autofac没有用参数击中构造函数【英文标题】:Autofac not hitting constructor with parameter 【发布时间】:2018-05-02 18:56:22 【问题描述】:

Autofac 的默认值是使用参数最多的构造函数,但它一直在使用无参数的默认构造函数。

消费类:

using AlbumApp.Core.Common.Contracts;
using AlbumApp.Core.Common.UI.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlbumApp.Admin.ViewModels

  public class MainViewModel : ViewModelBase
  
    private static IServiceFactory _serviceFactory;

    public MainViewModel()  

    public MainViewModel(IServiceFactory serviceFactory)
     _serviceFactory = serviceFactory; 

    private DashboardViewModel _dashboardViewModel = new DashboardViewModel(_serviceFactory);

    public DashboardViewModel DashboardViewModel  get  return _dashboardViewModel;  private set    // = new DashboardViewModel();
  

AutofacLoader:

using AlbumApp.Client.Proxies;
using AlbumApp.Core.Common.Contracts;
using Autofac;
using System.Reflection;

namespace AlbumApp.Admin.Bootstrapper

  public static class AutoFacLoader
  
    public static IContainer Init()  
      var builder = Builder();
      return builder.Build(); 

    public static ContainerBuilder Builder() 
      var builder = new ContainerBuilder();
      builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
        .InNamespace("AlbumApp.Admin.ViewModels").SingleInstance();
      builder.RegisterType<ServiceFactory>().As<IServiceFactory>();

      return builder; 
  

App.xaml.cs

using AlbumApp.Admin.Bootstrapper;
using AlbumApp.Core.Common.Core;
using System.Windows;

namespace AlbumApp.Admin

  /// <summary>
  /// Interaction logic for App.xaml
  /// </summary>
  public partial class App : Application
  
    protected override void OnStartup(StartupEventArgs e)
    
      base.OnStartup(e);

      ObjectBase.Container = AutoFacLoader.Init();

    
  

当我在builder.Build 上设置breakpoint 并检查ComponentRegistry 时,它包含ServiceFactory

Activator = ServiceFactory (ReflectionActivator), Services = [AlbumApp.Core.Common.Contracts.IServiceFactory], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope

我还在MainViewModel 的两个构造函数上设置了一个断点,并且只命中了默认构造函数,因此_serviceFactory 为空。

如何让 Autofac 注入 ServiceFactory

在无参数构造函数上调用堆栈:

AlbumApp.Admin.exe!AlbumApp.Admin.ViewModels.MainViewModel.MainViewModel() 第 15 行 C# AlbumApp.Admin.exe!AlbumApp.Admin.MainWindow.MainWindow() 第 30 行 C# [本机到托管转换] [托管到本地转换] mscorlib.dll!System.RuntimeType.CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref System.Threading.StackCrawlMark stackMark) 未知 mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic) 未知 mscorlib.dll!System.RuntimeType.CreateInstanceImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfoculture, object[] activationAttributes, ref System.Threading.StackCrawlMark stackMark) 未知 mscorlib.dll!System.Activator.CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfoculture, object[] activationAttributes) 未知 mscorlib.dll!System.Activator.CreateInstance(System.Type type, object[] args) 未知 System.Xaml.dll!System.Xaml.Schema.SafeReflectionInvoker.CreateInstanceCritical(System.Type type, object[] arguments) 未知 System.Xaml.dll!System.Xaml.Schema.SafeReflectionInvoker.CreateInstance(System.Type type, object[] arguments) 未知 System.Xaml.dll!System.Xaml.Schema.XamlTypeInvoker.CreateInstanceWithActivator(System.Type type, object[] arguments) 未知 System.Xaml.dll!System.Xaml.Schema.XamlTypeInvoker.CreateInstance(object[] arguments) 未知 System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstanceWithCtor(System.Xaml.XamlType xamlType, object[] args) 未知 System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(System.Xaml.XamlType xamlType, object[] args) 未知 System.Xaml.dll!MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateInstance(System.Xaml.XamlType xamlType, object[] args) 未知 System.Xaml.dll!System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(MS.Internal.Xaml.Context.ObjectWriterContext ctx) 未知 System.Xaml.dll!System.Xaml.XamlObjectWriter.WriteStartMember(System.Xaml.XamlMember 属性)未知 System.Xaml.dll!System.Xaml.XamlWriter.WriteNode(System.Xaml.XamlReader 阅读器)未知 PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.TransformNodes(System.Xaml.XamlReader xamlReader, System.Xaml.XamlObjectWriter xamlWriter, bool onlyLoadOneNode, bool skipJournaledProperties, bool shouldPassLineNumberInfo, System.Xaml.IXamlLineInfo xamlLineInfo, System.Xaml.IXamlLineInfoConsumer xamlLineInfoConsumer , MS.Internal.Xaml.Context.XamlContextStack 堆栈, System.Windows.Markup.IStyleConnector styleConnector) 未知 PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader xamlReader, System.Xaml.IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, System.Xaml.XamlObjectWriterSettings settings, System.Uri baseUri) 未知 PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader xamlReader, bool skipJournaledProperties, object rootObject, System.Xaml.Permissions.XamlAccessLevel accessLevel, System.Uri baseUri) 未知 PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, object parent, bool closeStream) 未知 PresentationFramework.dll!System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream 流,System.Windows.Markup.ParserContext pc)未知 PresentationFramework.dll!System.Windows.Application.LoadComponent(System.Uri resourceLocator, bool bSkipJournaledProperties) 未知 PresentationFramework.dll!System.Windows.Application.DoStartup() 未知 PresentationFramework.dll!System.Windows.Application..ctor.AnonymousMethod__1_0(对象未使用)未知 WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate 回调,对象 args,int numArgs)未知 WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) 未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.WrappedInvoke(System.Delegate 回调,对象 args,int numArgs,System.Delegate catchHandler)未知 WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() 未知 WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(对象状态)未知 mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态, bool preserveSyncCtx) 未知 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态, bool preserveSyncCtx) 未知 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态) 未知 WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state) 未知 WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() 未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() 未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd,int msg,System.IntPtr wParam,System.IntPtr lParam,ref bool 处理)未知 WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd,int msg,System.IntPtr wParam,System.IntPtr lParam,ref bool 处理)未知 WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) 未知 WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate 回调,对象 args,int numArgs)未知 WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) 未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.WrappedInvoke(System.Delegate 回调,对象 args,int numArgs,System.Delegate catchHandler)未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority 优先级,System.TimeSpan 超时,System.Delegate 方法,对象参数,int numArgs)未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority 优先级,System.Delegate 方法,对象 arg)未知 WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) 未知 [本机到托管转换] [托管到本地转换] WindowsBase.dll!System.Windows.Threading.Dispatcher.TranslateAndDispatchMessage(参考 System.Windows.Interop.MSG 消息)未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) 未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame 框架) 未知 WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() 未知 PresentationFramework.dll!System.Windows.Application.RunDispatcher(对象忽略)未知 PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window 窗口) 未知 PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window 窗口) 未知 PresentationFramework.dll!System.Windows.Application.Run() 未知 AlbumApp.Admin.exe!AlbumApp.Admin.App.Main() 未知 [本机到托管转换] [托管到本地转换] mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.RuntimeAssembly 程序集,字符串 [] args)未知 mscorlib.dll!System.AppDomain.ExecuteAssembly(字符串 assemblyFile,System.Security.Policy.Evidence assemblySecurity,string[] args)未知 Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 未知 mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(对象状态)未知 mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态, bool preserveSyncCtx) 未知 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态, bool preserveSyncCtx) 未知 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态) 未知 mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() 未知

【问题讨论】:

你能在构造函数上添加一个断点并发布堆栈跟踪吗?该类型可能没有被 Autofac 初始化。 什么堆栈跟踪?没有抛出错误,因此没有堆栈跟踪。它永远不会使用 IServiceFactory serviceFactory 参数命中构造函数。 我的意思是当无参数构造函数被命中时调用堆栈。 已发布。 你的类不是由 Autofac 而是由 WPF 构建的。您如何将您的AutoFacLoader 链接到您的 WPF 应用程序?我对 WPF 了解不够,但问题似乎就在那里。 【参考方案1】:

ViewModelBase 类包含 AutoFac Container,它被填充到 App.xaml.cs 中。通过从Container 解析它们来初始化ViewModels

更新 MainViewModel.cs

  public class MainViewModel : ViewModelBase
  
    public MainViewModel()   

    public DashboardViewModel DashboardViewModel 
      get  return Container.Resolve<DashboardViewModel>();     private set   

    public MaintainAlbumsViewModel MaintainAlbumsViewModel 
      get  return Container.Resolve<MaintainAlbumsViewModel>();      private set   

    public OrdersViewModel OrdersViewModel 
      get  return Container.Resolve<OrdersViewModel>();        private set  
    
  

【讨论】:

以上是关于Autofac没有用参数击中构造函数的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 Autofac 将已解析对象的列表注入构造函数?

如何使用 Xamarin 和 Autofac 将构造函数依赖项注入 ViewModel?

[Asp.Net Core]Autofac单抽象多实现构造函数注入

[Asp.Net Core]Autofac单抽象多实现构造函数注入

Autofac--注册组件--3属性和方法注入

Autofac + WCF REST 4.0