最近很头疼一个问题是,接口通过泛型方法,传入一个接口然后再传命名空间和类名参数进行查找实现该接口的所有成员,找到了就返回实例化对应接口返回,提供在外的泛型方法动态访问对应实现接口的方法!有没有人可以指点一下,在线熬夜等!
```c#
public interface TestInterface
{
int send();
}
class A : TestInterface
{
public int send()
{
throw new NotImplementedException();
}
}
class B : TestInterface
{
public int send()
{
throw new NotImplementedException();
}
}
static class ReflectionHelper
{
public static TInterface TestInterface<TInterface>(string NamespaceName, string ClassName)
{
///获取泛型TInterface所有实现该接口全部类。
///根据命名空间:NamespaceName和类名:ClassName 查找是否存在
///存在返回对应接口提供访问
return (TInterface)(object)null;
}
}
public class Program
{
public static void TestInterfaceFunction()
{
var Interface = ReflectionHelper.TestInterface<TestInterface/*传入接口*/>("命名空间", "B");
if (Interface != null)//确保找到实现该接口的实体类
{
Interface.send();//需要调用B类的SEND方法
}
}
```
首先,要实现动态查找实现特定接口的类,可以使用反射来实现。以下是解决这个问题的步骤:
Assembly.GetExecutingAssembly().GetTypes()
来获取当前程序集中的所有类型。Activator.CreateInstance(type)
实例化这些类,并将它们添加到一个列表中。以下是一个示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public static List<T> FindImplementingClasses<T>(string namespaceName, string className) where T : class
{
List<T> implementingClasses = new List<T>();
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); // 获取所有程序集
foreach (Assembly assembly in assemblies)
{
Type[] types = assembly.GetTypes(); // 获取程序集中的所有类型
foreach (Type type in types)
{
if (type.Namespace == namespaceName && type.Name == className && type.GetInterfaces().Contains(typeof(T)))
{
// 找到了实现指定接口的类
T implementingClass = (T)Activator.CreateInstance(type);
implementingClasses.Add(implementingClass);
}
}
}
return implementingClasses;
}
这样,你就可以通过调用FindImplementingClasses
方法来查找实现了特定接口的类,并获取它们的实例,然后可以在外部使用这些实例来调用它们的方法。
List<IMyInterface> implementingClasses = FindImplementingClasses<IMyInterface>("MyNamespace", "MyClass");
foreach (IMyInterface implementingClass in implementingClasses)
{
implementingClass.SomeMethod();
}
请注意,上述代码中的IMyInterface
是一个自定义的接口,你需要将它替换为你实际使用的接口。另外,"MyNamespace"
和"MyClass"
是示例参数,你需要将它们替换为实际的命名空间和类名。
最近很头疼一个问题是,接口通过泛型方法
也就是你是实际项目,那我们就直接给开箱即用的东西----------微软已经做好了,你不需要自己做
如果你非要跟着那个园子玩“技术”就当我们没说 :(
net4.62以上版本
nuget:Microsoft.Extensions.DependencyInjection
ServiceCollection services = new ServiceCollection();
var assembly = Assembly.GetExecutingAssembly();
//查找本assembly里所有实现了某个接口的对象
foreach (Type type in assembly.GetTypes())
{
if (typeof(TestInterface).IsAssignableFrom((Type)type) && !type.IsAbstract)
{ //这里有声明周期控制,我不知道你的应用,做为demo,我用全局单件
services.TryAdd(ServiceDescriptor.Singleton(typeof(TestInterface), type));
}
}
var ServiceProvider = services.BuildServiceProvider();
var obj = ServiceProvider.GetServices<TestInterface>()
.OfType<A>()
.FirstOrDefault();
var i = obj?.send();
解决这个问题的一种方法是使用反射来动态查找实现了指定接口的类,并实例化对应接口返回。下面是一个C#示例代码,演示如何通过泛型方法实现这一功能:
using System;
using System.Linq;
using System.Reflection;
public interface IMyInterface
{
void MyMethod();
}
public class MyImplementation1 : IMyInterface
{
public void MyMethod()
{
Console.WriteLine("MyImplementation1 - MyMethod is called!");
}
}
public class MyImplementation2 : IMyInterface
{
public void MyMethod()
{
Console.WriteLine("MyImplementation2 - MyMethod is called!");
}
}
public static class InterfaceResolver
{
public static T Resolve<T>(string namespaceName, string className) where T : class
{
// 查找实现了指定接口的类型
Type targetType = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => typeof(T).IsAssignableFrom(t) && t.Namespace == namespaceName && t.Name == className);
if (targetType != null)
{
// 实例化对应接口返回
T instance = Activator.CreateInstance(targetType) as T;
return instance;
}
return default;
}
}
public class Program
{
public static void Main()
{
// 查找并实例化实现了IMyInterface接口的类
IMyInterface instance1 = InterfaceResolver.Resolve<IMyInterface>("YourNamespace", "MyImplementation1");
IMyInterface instance2 = InterfaceResolver.Resolve<IMyInterface>("YourNamespace", "MyImplementation2");
// 调用对应接口的方法
instance1?.MyMethod(); // 输出: MyImplementation1 - MyMethod is called!
instance2?.MyMethod(); // 输出: MyImplementation2 - MyMethod is called!
}
}