开发者

Sending My Own Arguments To A Event Handler?

开发者 https://www.devze.com 2023-02-16 03:19 出处:网络
I\'m working with AssemblyResolve specifically.Here is my code first, then my question follows: var a = AppDomain.CurrentDomain;

I'm working with AssemblyResolve specifically. Here is my code first, then my question follows:

var a = AppDomain.CurrentDomain;
a.AssemblyResolve += new ResolveEventHandler(HandleIt);

Private Assembly HandleIt(object sender, ResolveEventArgs args){
    //Does stuff, returns an assembly
}

So I add HandleIt to my AssemblyResolve event. How can I add it to that event and pass an argument with it like:

a.AssemblyResolve += new ResolveEventHandler(HandleIt(AnArgument));

This is throwing me off since HandleIt takes arguments, but none are explicetly passed when it is added to the AssemblyResolve event. I would expect something like:

a.AssemblyResolve += new ResolveEventHandler(HandleIt(aSender,someArgs));

So yeah, I just want to be able to send another argument to my HandleIt function when adding it to my AssemblyResolve event.

Hope that makes sense, thanks.

Addendum:

if(aBool){
    a.AssemblyResolve += new ResolveEventHandler(HandleA);
}
else{
    a.AssemblyResolve += new ResolveEventHandler(HandleB);
}

HandleA(object sender, ResolveEventArgs args){
    Handle(true);
}
HandleB(object sender, ResolveEventArgs args){
    Handle(false);
}
Handle(bool isA){

}

-vs-

if(aBool)开发者_如何学运维{
    a.AssemblyResolve += (object s, ResolveEventArgs a) => Handle(s,a,true);
}
else{
    a.AssemblyResolve += (object s, ResolveEventArgs a) => Handle(s,a,false);
}

Handle(object sender, ResolveEventArgs args, bool isA){

}


When the event is fired arguments are passed to the method if you would like to bind additional arguments you could do that with a lambdaexpression

var a = AppDomain.CurrentDomain;
a.AssemblyResolve += (object s,ResolveEventArgs a) => HandleIt(s,a,someArgument);

Private Assembly HandleIt(object sender, ResolveEventArgs args, SomeType arg){
    //Does stuff, returns an assembly
}

where someArgument is the value you wish to bind.

This is essentially using lambdas to do a partial application of a function. Something that C# doesn't support directly but is very common in other languages. Partial application is very closely related to Currying that exists in languages such as F# and Haskell of course (since the concept gets it's name from Haskell Curry) and various other functional langauages. They differ in the result type.

They are both related to closures (as the concept in the above code is called) and in languages that don't support partial application or currying you can use closures to accomplish something similar. However be aware that closures differ from partial application in ways that can create some surprising bugs. E.g.

int i = 1;
Func<int> f = () => i;
i = 2;

System.Console.WriteLine(f());

prints 2 to the console. Because closures captures a reference to a variable not the value of said variable. This is a common error in for loops, when closing over the loop variable(s) of the for loop.


AppDomain.CurrentDomain will raise the event and pass parameters, the += line is simply registering a handler to the event, parameters there would not make any sense.

Analogy:

You register your address with the postman, and he deilivers mail to that address later. When you register at the post office, you do not hand them the mail you want delivered to you later!


It's not possible. HandleIt in this case is a delegate to and has to match the signature of ResolveEventHandler

a.AssemblyResolve += new ResolveEventHandler(HandleIt);

Setting it in this line just tells the code what to execute when AssemblyResolve is raised the thing that raises the AssemblyResolved event will pass it's parameters. You could re-raise another event with your own parameters and hook that to another handler (or just call a method).

EDIT: Or maybe you can with Lamda's :o


A bit more technical: You are registering a delegate to your method with the event. This is something else than a call to the method. It is a bit similar to this:

Action<object, ResolveEventArgs> handleItDelegate = HandleIt;

When the event is fired, the delegate is invoked. The analogy of my sample would be:

handleItDelegate(sender, eventArgs);

UPDATE:
In a comment, you clarified, what you want to achieve: You want to trigger the event, so your assembly is loaded. You can't do that, the way you think it works. To load your assembly manually, just do so, no need for the event. The event is called, when the runtime tries to resolve a referenced assembly, but can't find it.

0

精彩评论

暂无评论...
验证码 换一张
取 消