zoukankan      html  css  js  c++  java
  • .NET的依赖注入框架Microsoft.Extensions.DependencyInjection,支持注入未绑定的泛型类(Unbound generic type)

    C#的关键字typeof可以用来获取未绑定的泛型类/接口(Unbound generic type)的Type类实例,未绑定的泛型类/接口(Unbound generic type)就是指没有指定类型参数的泛型类/接口,如下代码所示:

    using System;
    
    namespace NET5UnboundGenericDependencyInjectionDemos
    {
        /// <summary>
        /// 泛型类Container<T>
        /// </summary>
        /// <typeparam name="T">泛型类型参数</typeparam>
        class Container<T>
        {
    
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Type unboundGenericType = typeof(Container<>);//通过typeof关键字,获取未绑定的泛型类Container<T>的Type类实例
    
                Console.WriteLine(unboundGenericType.ToString());
    
                Console.WriteLine("Press any key to end...");
                Console.ReadKey();
            }
        }
    }

    运行上面代码,结果如下:

    可以看到Type类实例unboundGenericType输出的信息中,泛型类Container<T>的类型参数T,并没有被指定为具体的类型,所以是未绑定的泛型类。

    未绑定的泛型类常常被用于依赖注入中,这样可以大大增加代码的复用性,而微软的依赖注入框架Microsoft.Extensions.DependencyInjection支持注入未绑定的泛型类。

    首先我们创建一个.NET 5.0控制台项目,然后引入nuget包:Microsoft.Extensions.DependencyInjection

    项目的代码如下所示:

    using Microsoft.Extensions.DependencyInjection;
    using System;
    
    namespace NET5UnboundGenericDependencyInjectionDemos
    {
        /// <summary>
        /// 泛型接口IContainer<T>
        /// </summary>
        /// <typeparam name="T">泛型类型参数,where T : new()约束保证类型T具有公共无参数构造函数</typeparam>
        interface IContainer<T> where T : new()
        {
            T Element
            {
                get;
            }
    
            /// <summary>
            /// 显示泛型类型参数T的Type类型
            /// </summary>
            void ShowElementType();
        }
    
        /// <summary>
        /// 泛型类Container<T>,实现接口IContainer<T>
        /// </summary>
        /// <typeparam name="T">泛型类型参数,where T : new()约束保证类型T具有公共无参数构造函数</typeparam>
        class Container<T> : IContainer<T> where T : new()
        {
            protected T element;
    
            public Container()
            {
                element = new T();
            }
    
            public T Element
            {
                get
                {
                    return element;
                }
            }
    
            /// <summary>
            /// 显示泛型类型参数T的Type类型
            /// </summary>
            public void ShowElementType()
            {
                Console.WriteLine(element.GetType().ToString());
            }
        }
    
        /// <summary>
        /// 类People,作为泛型接口IContainer<T>和泛型类Container<T>的类型参数T
        /// </summary>
        class People
        {
            public void Speak()
            {
                Console.WriteLine("I'm a people!");
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                IServiceCollection serviceDescriptors = new ServiceCollection();
                serviceDescriptors.AddTransient(typeof(IContainer<>), typeof(Container<>));//注册未绑定的泛型接口IContainer<T>和未绑定的泛型类Container<T>的依赖注入关系
    
                IContainer<People> container = null;//声明关闭的泛型接口IContainer<People>变量container,下面使用依赖注入来为其赋值
    
                using (ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider())
                {
                    using (IServiceScope serviceScope = serviceProvider.CreateScope())
                    {
                        container = serviceScope.ServiceProvider.GetService<IContainer<People>>();//使用依赖注入为泛型接口IContainer<People>变量container赋值,依赖注入框架Microsoft.Extensions.DependencyInjection会构造一个关闭的泛型类Container<People>实例,赋值给IContainer<People> container
                    }
                }
    
                Console.WriteLine(container.GetType().ToString());//显示泛型接口IContainer<People>变量container的实际类型
                container.ShowElementType();//调用泛型接口IContainer<People>的ShowElementType方法
                container.Element.Speak();//调用泛型接口IContainer<People>的类型参数People的Speak方法
    
                Console.WriteLine("Press any key to end...");
                Console.ReadKey();
            }
        }
    }

    运行上面代码,结果如下:

    我们可以看到,使用依赖注入框架Microsoft.Extensions.DependencyInjection,我们可以为关闭的泛型接口(Closed generic type)IContainer<People>,来注入关闭的泛型类(Closed generic type)Container<People>,关闭的泛型类/接口(Closed generic type)就是指指定了具体类型参数的泛型类/接口,上面代码中泛型的类型参数就是People类。

    注意上面代码中,我们在注册依赖注入关系的时候(AddTransient),是注册的未绑定的泛型接口IContainer<T>和未绑定的泛型类Container<T>的依赖注入关系,但是依赖注入框架Microsoft.Extensions.DependencyInjection,还是可以为关闭的泛型接口IContainer<People>,获得关闭的泛型类Container<People>。

  • 相关阅读:
    请问大侠,为什么将Trusted_Connection=true改为Trusted_Connection=false可以消除错误:"用户 'NT AUTHORITY\NETWORK SERVICE' 登录失败。"?
    以前本地机装的是DOTNETNUKE2.0.3好用的,现在装DOTNETNUKE2.1.2出问题了...,请帮忙
    solution to display [PAGETITLE] when using smculloch's skin for dotnetnuke
    Solution to 'DotNetNuke unavailable' when using vs.net open DotNetNuke.sln
    非过程式编程语言
    Visual Studio .NET 无法创建应用程序 。问题很可能是因为本地 Web 服务器上没有安装所需的组件
    Design Samples & Dotnetnuke Skins
    在web host 的DotNetNuke中添加连接时出现的错误及解决办法
    STL中的unique()和lower_bound ,upper_bound
    读书笔记 UltraGrid(2)
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/14707127.html
Copyright © 2011-2022 走看看