我正在尝试动态创建代理类.我知道有一些非常好的框架可以做到这一点,但这纯粹是一个宠物项目作为一个学习练习,所以我想自己做.
例如,如果我有以下类实现接口:
interface IMyInterface
{
void MyProcedure();
}
class MyClass : IMyInterface
{
void MyProcedure()
{
Console.WriteLine("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
为了拦截这个类的方法以便记录它们,我正在创建另一个类(我的代理类版本),它实现相同的接口但包含对"真实"类的引用.此类执行操作(例如,日志记录),然后在真实类上调用相同的方法.
例如:
class ProxyClass : IMyInterface
{
private IMyInterface RealClass { get; set; }
void MyProcedure()
{
// Log the call
Console.WriteLine("Logging..");
// Call the 'real' method
RealClass.MyProcedure();
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用者调用代理类上的所有方法(我使用基本的home-brew IoC容器来注入代理类来代替真正的类).我正在使用此方法,因为我希望能够RealClass在运行时将其换出到另一个实现相同接口的类.
有没有办法ProxyClass在运行时创建并填充其RealClass属性,以便它可以用作真实类的代理?是否有一种简单的方法可以做到这一点,还是需要使用类似的东西Reflection.Emit并生成MSIL?
自从这个问题提出以来已经过去了 6 年,我本来希望今天能有一个简单的解决方案......但似乎没有。
注意:请阅读其他问题以理解这个概念:
几分钟后,我尝试实现一个简单的示例,并且几乎已经完成了。同时我仍然看到一些问题。我想知道是否有人有关于如何让它变得更好的想法。
使用.NET 6(代码如下)。
问题 1:我不喜欢我们所说的泛型,使用TTargetas User,我们还需要传递T ID类型......为什么通过传递User不足以让编译器知道ID数据类型?示例:class UserService : IBaseDBOperation1<User, Guid>为什么不呢class UserService : IBaseDBOperation1<User>?
问题2:我知道现在我们可以使用带有代码的方法的接口,但是为什么我们仍然需要用两种数据类型精确地定义变量类型并且使用var还不够?好吧,我们可以使用var,但是这样方法就不可见了。而不是:IBaseDBOperation1<User, Guid> serviceU1 = new UserService();........ var serviceU2 = new UserService();...... 这第二个变量将看不到其他方法。
最后一点:如果 C# 允许我们用多个抽象类扩展一个类,那么一切都会变得容易多了……(截至目前,我们的抽象类仅限于 1 个)。
目标:完成6 年前提出的问题中提出的问题......换句话说......避免复制/粘贴,并以某种方式将多个“操作类”“注入/关联/注册/定义”到服务中....那些“操作类”将在多个不同的服务中大量重用...并且我确实希望有一种“干净/漂亮”的方式来设置它,但同时,消费者不应该担心“较低/更深”的杠杆继承泛型。
代码
public abstract class BaseDBEntry<T> where T : struct
{
protected BaseDBEntry()
{
CreatedOn = DateTime.Now; …Run Code Online (Sandbox Code Playgroud)