c# – 将Autofac容器传递给WPF UserControl

c# – 将Autofac容器传递给WPF UserControl,第1张

概述我正在使用autofac来解析 WPF应用程序中的Views和ViewModel. IComponentContext将自动传递到View中. 一个例子: public BusinessAuto(int proposedCoverageId, IComponentContext componentContext) { DataContext = componentConte 我正在使用autofac来解析 WPF应用程序中的VIEws和viewmodel. IComponentContext将自动传递到VIEw中.

一个例子:

public Businessauto(int proposedCoverageID,IComponentContext componentContext)    {        DataContext = componentContext.Resolve<Businessautoviewmodel>(new TypedParameter(typeof(Int32),proposedCoverageID));        InitializeComponent();    }

在此视图的XAML中,创建了具有自己的viewmodel的UserControl.一个例子:

<userControl:AdditionalCoveragesControl margin="0,10"/>

autofac不会创建UserControl(VIEw是),因此autofac无法将依赖项注入UserControl的构造函数中.

如何将对IComponentContext的引用转换为在初始VIEw的XAML中声明的UserControl?

我觉得我要么需要autofac以某种方式创建我的UserControl,我需要恢复到不鼓励的全局静态容器(ick),或者我必须使用DependencyProperty来传递容器(也是ick).

解决方法 我不会注入(有效的)你的容器,因为这是一种称为服务定位器的低级控制反转形式,缺点可以通过你当前的情况来总结:你最终需要将容器注入一切.

相反,您需要从“负责创建的这个组件是什么,以及它需要做什么?”的角度来解决问题.

正如Lonni-Loki所提到的,一个选择是注入一个完全形成的控件,但我不同意这一点:如果主视图有责任创建这个子组件,那么它应该创建它 – 但为了促进这个责任,你应该注入主视图与服务/模型/等,然后需要传递或以其他方式用于创建它. autofac的工厂方法存根非常适用于此:

例如,如果子视图需要IFooviewmodel,则可以使用Func< IFooviewmodel< (在上下文中注册的工厂方法),然后它可以用于“按需提供”新包含的视图. (或Func< arg1,arg2等,IFooviewmodel>,根据您的需要)

一个方便的经验法则是在考虑X类时,首先在任何地方“新建”任何东西,然后将其传递给构造函数.现在看看代码并问自己“如果我想要一个X类的实例,我需要传递什么构造函数?”那些是你的依赖.

让我们来看一个更实际的例子…说你有这样的结构:

>应用程序创建MainWindow
> MainWindow创建SubVIEw1,需要IMainWindowviewmodel
> SubVIEw1需要ISubVIEw1Model,IFooService
> SubVIEw1创建SubVIEw2
> SubVIEw2需要ISubVIEw2Model,IbarService

所以我们的ctors看起来像:

public MainWindow(IMainWindowviewmodel viewmodel,Func<SubVIEw1> subVIEw1Factory)public SubVIEw1(ISubVIEw1Model viewmodel,IFooService fooService,Func<IFooService,SubVIEw2> subVIEw2Factory)public SubVIEw2(    ISubVIEw2Modelviewmodel viewmodel,IbarService barService)

在设置容器时,你会有这样的事情:

(注意,我使用了各种IoC容器,因此我的autofac语法可能会生锈)

var builder = new ContainerBuilder();// Simple bit,register implementations for viewmodel,servicesbuilder.RegisterType<MainWindowviewmodel>.As<IMainWindowviewmodel>();builder.RegisterType<SubVIEw1Model>.As<ISubVIEw1Model>();builder.RegisterInstance<FooService>.As<IFooService>();// ok,lemme see if I can remember Expression Syntax...// Simple case: 'static' resolution of subvIEw// We want a func that takes no args and returns us a fully-initialized//  SubVIEw1builder.Register<Func<SubVIEw1>>(context =>{    // Since all the bits of a subvIEw1 are registered,simply    // resolve it and return    var vIEw = context.Resolve<SubVIEw1>();    return () => vIEw;});// Complicated case - lets say this viewmodel depends// on foo service,which it uses to determine which // bar service to usebuilder.Register<Func<IFooService,SubVIEw2>>(context =>{    // and our vIEw model    var vm = context.Resolve<ISubVIEw2viewmodel>();    return (service) =>    {        var barService = new barService(service);        return new SubVIEw2(vm,barService);    };});

光荣(在我看来,仅限于)IoC容器的使用是“你弄清楚如何根据我已经告诉你的东西得到所有的部分” – 否则,你不妨使用手动注射,你在哪里手工传递依赖关系.也就是说,我们可能复杂的MainWindow构建现在只是:

container.Resolve<MainWindow>();

我希望我没有在代码中输入太多的拼写错误/错误,但我还没有使用autofac一段时间.

总结

以上是内存溢出为你收集整理的c# – 将Autofac容器传递给WPF UserControl全部内容,希望文章能够帮你解决c# – 将Autofac容器传递给WPF UserControl所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1217792.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存