首页新闻招聘找找看知识库

dotnet core动态选取程序集,请大神给个思路

0
悬赏园豆:50 [已解决问题] 解决于 2018-01-04 11:16

假设有三个dll(A.dll,B.dll,C.dll),每个里面都有一个名为 Library.GetName() 的方法,实现各不相同。但是各自的命名空间不一样。

目前希望设计一个程序,引用这三个dll,并提供一个WebApi。

根据用户身份不同,调用的不同dll中的同一个名称方法。

例如当用户以A身份访问的时候,返回A.dll中Library.GetName()执行的结果。

当用户以B身份访问的时候,返回B.dll中Library.GetName()执行的结果。

 

一开始想使用依赖注入,但是貌似目前见过的都是一个Interface对一个class的注入方式,不太清楚一个接口对应多个类的方式。

 

本来可以写switch case来解决问题,但是考虑到以后可以扩展更多的dll,想以这种方式实现。

 

请大神指点。给出思路就可以,十分感谢!

写代码的相声演员的主页 写代码的相声演员 | 初学一级 | 园豆:190
提问于:2017-12-26 17:01
< >
分享
最佳答案
1

这正是抽象工厂结合 .net core 依赖注入的用武之地,示例代码如下

using System;
using Microsoft.Extensions.DependencyInjection;

namespace Q101389
{
    class Program
    {
        static void Main(string[] args)
        {
            IServiceCollection services = new ServiceCollection();
            services.AddScoped<ILibraryFactory, LibraryFactory>()
                .AddScoped<LibraryA, LibraryA>()
                .AddScoped<LibraryB, LibraryB>()
                .AddScoped<LibraryC, LibraryC>();

            IServiceProvider serviceProvider = services.BuildServiceProvider();
            var libraryFactory = serviceProvider.GetService<ILibraryFactory>();

            ILibrary library =  libraryFactory.CreateLibrary<LibraryA>();
            Console.WriteLine(library.GetName()); //Output is LibraryA

            library = libraryFactory.CreateLibrary<LibraryB>();
            Console.WriteLine(library.GetName()); //Output is LibraryB
        }
    }

    public interface ILibrary
    {
        string GetName();
    }

    public interface ILibraryFactory
    {
        ILibrary CreateLibrary<T>() where T : ILibrary;
    }

    public class LibraryFactory : ILibraryFactory
    {
        private IServiceProvider _serviceProvider;

        public LibraryFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public ILibrary CreateLibrary<T>() where T : ILibrary
        {
            return _serviceProvider.GetService<T>() as ILibrary;
        }
    }

    public class LibraryA : ILibrary
    {
        public string GetName()
        {
            return nameof(LibraryA);
        }
    }

    public class LibraryB : ILibrary
    {
        public string GetName()
        {
            return nameof(LibraryB);
        }
    }

    public class LibraryC : ILibrary
    {
        public string GetName()
        {
            return nameof(LibraryC);
        }
    }
}
收获园豆:40
dudu | 高人七级 |园豆:34672 | 2017-12-26 17:37
其他回答(3)
0

s数组注入.在使用的时候从注入的实例数组中筛选出特定的实例,使用.

收获园豆:2
吴瑞祥 | 园豆:25162 (高人七级) | 2017-12-26 17:13
0

初始化时:加载进去后,反射获取Type集合,然后linq,然后放入hash。

运行时:最后根据你对应运算关系(或者配置关系),反射创建该interface,调用函数即可。

收获园豆:5
花飘水流兮 | 园豆:4087 (老鸟四级) | 2017-12-26 17:17

之前考虑过用反射,但是反射动态的创建对象,效率不是不高么?

我有点顾虑效率问题,所以想看看还有没有更优解。

另外,如果我dll里的方法很多的话,都使用Hash,内存开销是不是需要考虑?

支持(0) 反对(0) 写代码的相声演员 | 园豆:190 (初学一级) | 2017-12-26 17:33

@写代码的相声演员: mvc的controller本来就这么干的,你那么说微软...而且中间码到内存难道不是“反射”,更何况你这里已经是缓存type了。

支持(0) 反对(0) 花飘水流兮 | 园豆:4087 (老鸟四级) | 2017-12-26 17:54
0

http://docs.autofac.org/en/latest/advanced/keyed-services.html

1 //注入
2 var builder = new ContainerBuilder();
3 builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online);
4 builder.RegisterType<OfflineState>().Keyed<IDeviceState>(DeviceState.Offline);
5 
6 //获取
7 var r = container.ResolveKeyed<IDeviceState>(DeviceState.Online);
收获园豆:3
blackheart | 园豆:1173 (小虾三级) | 2017-12-31 11:28
   您需要登录以后才能回答,未注册用户请先注册