我有一个.dll文件,在那里,有一个名为A的方法。当我调用该方法时,我想调用我自己的方法,方法B.所以我的问题是,是否可以调用方法方法A完成后立即B?
Offcourse我可以调用方法A,然后手动调用方法B.但我想知道有没有办法自动执行此操作,也许有一个事件?因此,当方法A完成时,事件会以某种方式被触发,并且调用方法A.
编辑: 我无法控制.dll。所以我无法改变方法A中的任何内容。
答案 0 :(得分:3)
请看Aspect Oriented Programming (AOP),特别是PostSharp。
http://www.sharpcrafters.com/aop.net/msil-injection:
MSIL注射,或MSIL插入,是 修改MSIL的过程 现有方法的说明。 有人说我们注射或插入 现有的新指令 流动。
答案 1 :(得分:1)
如果你控制了定义方法A的类,那么我会选择事件方法。以下是MSDN Event Naming Guidelines之后的简短示例:
class Foo
{
public event EventHandler Did;
public void Do()
{
Console.WriteLine("Do");
this.OnDid(EventArgs.Empty);
}
protected void OnDid(EventArgs e)
{
var evt = this.Did;
if (evt != null)
{
evt(this, e);
}
}
}
class Program
{
public static void Main(string[] args)
{
var foo = new Foo();
foo.Did += (sender, e) => Console.WriteLine("Did");
foo.Do();
}
}
如果要为定义B
的类的每个实例运行方法A
,可以创建辅助方法来创建实例并立即添加事件处理程序。
public static Foo CreateFoo()
{
var foo = new Foo();
foo.Did += (sender, e) => Console.WriteLine("Did");
return foo;
}
答案 2 :(得分:1)
只有目标方法的合作(它调用委托或触发事件)或调用者(用调用方法的中间方法替换对A的调用)。
你也可以重新编写IL来修改A
以允许这样的回调(或理论上使用调试器API),但这要复杂得多。
包装器方法类似于:
var AWrapped = () => { A(); MyHelper(); };
并使用A
或更明确地将所有来电替换为AWrapped
:
原始来电者代码:
//...
A();
//...
并替换为:
//...
AWrapped();
//...
(如果要在多个地方使用,或者在多种类型中使用,那么我会使用静态函数(可能是扩展函数)来进行包装。)
答案 3 :(得分:1)
如果您无法控制dll,请编写包装类
public class WrapAnotherClass : AnotherClass
{
public EventHandler DoSomethingFinished;
public new void DoSomething()
{
base.DoSomething();
var temp = DoSomethingFinished;
if (temp != null)
{
temp(this, EventArgs.Empty);
}
}
}
public class AnotherClass
{
public void DoSomething()
{
Console.WriteLine("Do something!");
}
}
答案 4 :(得分:0)
如果方法A允许依赖注入,则可以通过注入自己的依赖项来实现。怎么样?可能其他擅长它的人可以告诉你,如果你的方法A允许依赖。我不擅长。
其次,您可以扩展包含方法A的类(如果它未密封)并覆盖方法A的功能以连接事件。现在到处使用扩展类的实例来调用方法A
答案 5 :(得分:0)
看到你无法访问代码,你必须创建一个包装器来封装它。
像这样:
class Wrapper
{
private A = new A(); //this is your closed .dll class
public event EventHandler DoneThing;
private void OnDoneThing()
{
if(DoneThing!=null)
{
DoneThing(this, EventArgs.Empty);
}
}
public void DoThing()
{
A.DoThing();
OnDoneThing();
}
}