假设有三个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,想以这种方式实现。
请大神指点。给出思路就可以,十分感谢!
这正是抽象工厂结合 .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);
}
}
}
s数组注入.在使用的时候从注入的实例数组中筛选出特定的实例,使用.
初始化时:加载进去后,反射获取Type集合,然后linq,然后放入hash。
运行时:最后根据你对应运算关系(或者配置关系),反射创建该interface,调用函数即可。
之前考虑过用反射,但是反射动态的创建对象,效率不是不高么?
我有点顾虑效率问题,所以想看看还有没有更优解。
另外,如果我dll里的方法很多的话,都使用Hash,内存开销是不是需要考虑?
@写代码的相声演员: mvc的controller本来就这么干的,你那么说微软...而且中间码到内存难道不是“反射”,更何况你这里已经是缓存type了。
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);