WPF 手撸插件 八 依赖注入

本文内容大量参考了:https://www.cnblogs.com/Chary/p/11351457.html  而且这篇文章总结的非常好。

1、注意想使用Autofac,Autofac是一个轻量级、‌高性能的依赖注入(‌DI)‌框架,‌主要用于.NET应用程序的组件解耦和管理。‌‌

        核心思想‌:‌将对象之间的依赖关系从应用程序中分离出来,‌以降低代码的耦合度,‌提高可维护性和可测试性。‌

‌        主要特点‌:‌

                轻量级:‌核心库只有几个DLL文件,‌易于与其他框架集成,‌对应用程序性能无影响。‌

                灵活性:‌提供多种注册方式,‌如XML配置文件、‌代码配置和属性注解等。‌

                高性能:‌在实例化对象时,‌能比其他DI框架更快地找到并创建所需的依赖项。‌

                生命周期管理:‌提供多种生命周期管理选项,‌如瞬态、‌作用域和单例等。‌

                AOP支持:‌可轻松与AOP框架集成,‌实现横切关注点的统一处理。

2、废话结束,我们直接上代码。我安装的是Autofac 3.0.0

2.1、整个官网示例。

using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac.Features.Indexed;

namespace ConsoleAppAutofac
{
    class Program
    {
        private static IContainer Container { get; set; }
        static void Main(string[] args)
        {

            var builder = new ContainerBuilder();//准备容器
            builder.RegisterType<ConsoleOutput>().As<IOutput>();//注册对象
            builder.RegisterType<TodayWriter>().As<IDateWriter>();//注册对象
            builder.RegisterInstance(new Dog());//实例注入
            builder.RegisterInstance(Singleton.Instance).ExternallyOwned();//将单例对象托管到IOC容器
            builder.Register(c => new Person() { Name = "张三", Age = 22 }); //Lambda表达式注入
            builder.RegisterGeneric(typeof(List<>));//注入泛型类

            builder.RegisterType<Doge>().As<IAnimal>();//映射对象,IAnimal被多次注册,以最后注册为准
            builder.RegisterType<Cat>().As<IAnimal>().PreserveExistingDefaults();//指定Cat为非默认值,PreserveExistingDefaults()修饰符,可以指定某个注册为非默认值

            //一个接口被多个实例对象实现,可以进行命名,注入的时候使用名字进行区分
            builder.RegisterType<Doge>().Named<IAnimal>("doge");
            builder.RegisterType<Doge>().Named<IAnimal>("pig");

            //Autofac.Features.Indexed.IIndex<K,V>是Autofac自动实现的一个关联类型。使用IIndex<K,V>作为参数的构造函数从基于键的服务中选择需要的实现
            builder.RegisterType<Doge>().Keyed<IAnimal>(AnumaType.Doge);//映射对象
            builder.RegisterType<Pig>().Keyed<IAnimal>(AnumaType.Pig);//映射对象
            builder.RegisterType<Pig>().Keyed<IAnimal>(AnumaType.Cat);//映射对象

            //自动装配,从容器中的可用对象中选择一个构造方法来创建对象,这个过程叫做自动装配。它是通过反射实现的,所以实际上容器创造对象的行为比较适合用在配置环境中
            //Autofac默认从容器中选择参数最多的构造函数。如果想要选择一个不同的构造函数,就需要在注册的时候就指定它:
            //这种写法将指定调用Person(string)构造函数,如该构造函数不存在则报错。
            builder.RegisterType<Person>().UsingConstructor(typeof(string));
            //额外的构造函数参数:
            //有两种方式可以添加额外的构造函数参数,在注册的时候和在检索的时候。在使用自动装配实例的时候这两种都会用到。
            //注册时添加参数,使用WithParameters()方法在每一次创建对象的时候将组件和参数关联起来。
            List<NamedParameter> pars = new List<NamedParameter>() { new NamedParameter("Age", 20), new NamedParameter("Name", "张三") };
            builder.RegisterType<Person>().WithParameters(pars);


            Container = builder.Build();//容器创建完毕

            List<string> list = Container.Resolve<List<string>>();
            var dog = Container.Resolve<IAnimal>();//通过IOC容器创建对象
            dog.SayHello();

            var pig = Container.ResolveNamed<IAnimal>("pig");//通过IOC容器创建对象
            pig.SayHello();


            var animal = Container.Resolve<IIndex<AnumaType, IAnimal>>();
            var cat = animal[AnumaType.Cat];
            cat.SayHello();

            WriteDate();

            Console.ReadLine();
        }

        public static void WriteDate()
        {
            using (var scope = Container.BeginLifetimeScope())
            {
                var writer = scope.Resolve<IDateWriter>();//通过IOC容器创建对象
                writer.WriteDate();//调用对象的方法
            }
        }
    }
    /// <summary>
    /// 设置枚举
    /// </summary>
    public enum AnumaType
    {
        Doge,Pig,Cat
    }
    public interface IOutput
    {
        void Write(string content);
    }

    public class ConsoleOutput : IOutput
    {
        public void Write(string content)
        {
            Console.WriteLine(content);
        }
    }

    public interface IDateWriter
    {
        void WriteDate();

    }

    public class TodayWriter : IDateWriter
    {
        private IOutput _output;
        public TodayWriter(IOutput output)
        {
            this._output = output;
        }

        public void WriteDate()
        {
            this._output.Write(DateTime.Today.ToShortDateString());
        }
    }

    public class Dog
    {
        public void Say()
        {
            Console.WriteLine("汪汪汪");
        }
    }

    public interface IAnimal
    {
        void SayHello();
    }
    public class Doge : IAnimal
    {
        public void SayHello()
        {
            Console.WriteLine("我是小狗,汪汪汪~");
        }
    }
    public class Cat : IAnimal
    {
        public void SayHello()
        {
            Console.WriteLine("我是小猫,喵喵喵~");
        }
    }
    public class Pig : IAnimal
    {
        public void SayHello()
        {
            Console.WriteLine("我是小猪,呼呼呼~");
        }
    }

    public class Person
    { 
        public Person(){}

        public Person(string name)
        {
            Name = name;

        }

        public Person(string name, int age):this(name)
        {
            Age = age;
        }

        public string Name { get; set; }
        public int Age { get; set; }
    }

    public class Singleton
    {
        // 私有静态实例,‌初始时为null
        private static Singleton instance = null;

        // 私有构造函数
        private Singleton() { }

        // 公共静态方法,‌提供全局访问点
        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }

}

输出结果如下图。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
WPF 中,View 和 ViewModel 的依赖注入可以通过以下几种方式来实现: 1. 通过构造函数注入: 在 ViewModel 的构造函数中,注入 View 中所需要的服务或者依赖项,例如: ``` public class MainViewModel { private readonly IMyService _myService; public MainViewModel(IMyService myService) { _myService = myService; } } ``` 在 View 中,通过创建 ViewModel 的实例,同时传入所需要的服务: ``` public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new MainViewModel(new MyService()); } } ``` 2. 通过属性注入: 在 ViewModel 中,通过属性注入需要的服务或者依赖项,例如: ``` public class MainViewModel { [Dependency] public IMyService MyService { get; set; } } ``` 在 View 中,通过依赖注入容器来实现属性的注入: ``` public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var container = new UnityContainer(); container.RegisterType<IMyService, MyService>(); DataContext = container.Resolve<MainViewModel>(); } } ``` 3. 通过方法注入: 在 ViewModel 中,通过方法注入需要的服务或者依赖项,例如: ``` public class MainViewModel { private IMyService _myService; [InjectionMethod] public void Initialize(IMyService myService) { _myService = myService; } } ``` 在 View 中,通过依赖注入容器来实现方法的注入: ``` public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var container = new UnityContainer(); container.RegisterType<IMyService, MyService>(); var mainViewModel = container.Resolve<MainViewModel>(); mainViewModel.Initialize(container.Resolve<IMyService>()); DataContext = mainViewModel; } } ``` 需要注意的是,以上三种方式都需要使用依赖注入容器来实现。在 WPF 中,常用的依赖注入容器包括 Unity、Autofac、Prism 等。具体使用哪个容器,可以根据项目的需要和个人偏好来选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为风而战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值