Inject Method with Mono.Cecil - vb.net

How can I inject a custom method into a .net assembly using mono.cecil, and then call it in the entrypoint?
I like to do this to implement security methods after the binary is built.

To inject method you need to get the type you want to add it the method and then add a MethoDefinition.
var mainModule = ModuleDefinition.ReadModule(assemblyPath);
var type = module.Types.Single(t => t.Name == "TypeYouWant");
var newMethodDef= new MethodDefinition("Name", MethodAttributes.Public, mainModule.TypeSystem.Void);
type.Methods.Add(newMethodDef);
To call this method form the entry point, you need to get the entry point MethodDefinition and the new injected MethodReference and add instruction in the entry point method to call the new injected method.
var newMethodRef = type.Methods.Single(m => m.Name == "Name").Resolve();
var entryPoint= type.Methods.Single(m => m.Name == "YourEntryPoint");
var firstInstruction = entryPoint.Body.Instructions.First();
var il = entryPoint.Body.GetILProcessor();
il.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Callvirt, newMethodRef));
mainModule.Write(assemblyPath);
Note: Yes I know its C# and not VB but I'm sure once you got the idea you can easily convert it to VB.

You can make use of the Module.Import() function.
Example Class can be seen in the video:
https://www.youtube.com/watch?v=heTCisgYjhs
Credits to TheUnknownProgrammer's importer class.

Related

Why is ruleSet not recognized in WebForms?

Given this validator:
public ThingValidator()
{
RuleSet("Subgroup", () =>
{
RuleFor(x => x.Apple).NotEmpty();
RuleFor(x => x.Peach).NotEmpty();
});
}
According to the documentation, the 'ruleSet' option should use my named ruleset. However, the suleSet symbol cannot be resolved.
var validator = new ThingValidator();
var thing = new Constituent();
var results = validator.Validate(thing, ruleSet: "Subgroup");
What am I missing?
I was stuck on this as well, but when I looked into the code, I found that while IValidator<T> has a Validate method, there are also Validate extensions methods in DefaultValidatorExtensions. The call with the ruleSet parameter in #mmcglynn's answer is actually to this extension method from DefaultValidatorExtensions:
public static ValidationResult Validate<T>(
this IValidator<T> validator, T instance,
IValidatorSelector selector = null,
string ruleSet = null)
This is why Resharper thinks that the ruleSet variable is unused - because it is not actually passed in. The string "children" passed in is for the 3rd parameter called ruleset, whereas the second parameter (which can take the RulesetValidatorSelector object) defaults to null.
This is extension method, declare namespace using FluentValidation and you can use it.
I think what you need it:
var results = validator.Validate(constituent, new RulesetValidatorSelector("Subgroup"));
or, closer to the example in the FluentValidation documentation
RulesetValidatorSelector ruleSet = new RulesetValidatorSelector();
var results = validator.Validate(constituent, ruleSet: "Children");
This will work, but ReSharper thinks that the ruleSet local variable is unused.

Ability to set the context of the expression

Is there a way to set the context of the expression in Dynamic Expresso library, so that we can do something like the following:
interpreter.Eval("FirstName", new Parameter("person", new { FirstName="Homer", LastName="Simpson"}));
rather than
interpreter.Eval("person.FirstName", new Parameter("person", new { FirstName="Homer", LastName="Simpson"}));
Maybe we could have a another option that would say that the first parameter is to be used as the context for the expression.
I guess there could also be another version of Parse and Eval methods that simply takes the expression text and a simple object value that will serve as the expression context.
Other than that and the lack of support for dynamic types, I am really liking this library. I had worked on something similar, but had not added support for extension methods and generic method calls.
Thanks for the great library,
Neal
There isn't a built-in solution but you can simulate it in many ways:
Option 1: Inject an expression
var workingContext = new { FirstName = "homer" };
var workingContextExpression = Expression.Constant(workingContext);
var firstNameExpression = Expression.Property(workingContextExpression, "FirstName");
var interpreter = new Interpreter();
interpreter.SetExpression("FirstName", firstNameExpression);
Assert.AreEqual(workingContext.FirstName, interpreter.Eval("FirstName"));
Basically I inject an expression using SetExpression method. The injected expression is the property that you want to be available.
Option 2: Use this/me/it variable
You can inject a variable that will contain your working object. I usually call it this (or me or it depending on the application).
var workingContext = new { FirstName = "homer" };
var interpreter = new Interpreter();
interpreter.SetVariable("this", workingContext);
Assert.AreEqual(workingContext.FirstName, interpreter.Eval("this.FirstName"));
Option 3: A combination of the previous solutions
var workingContext = new { FirstName = "homer" };
var interpreter = new Interpreter();
interpreter.SetVariable("this", workingContext);
var firstNameExpression = interpreter.Parse("this.FirstName").LambdaExpression.Body;
interpreter.SetExpression("FirstName", firstNameExpression);
Assert.AreEqual(workingContext.FirstName, interpreter.Eval("FirstName"));
Equal to the first solution but I generate the expression using the parser itself.
Consider that all solutions assume that you must have an Interpreter instance for each context.
Disclaimer: I'm the author of Dynamic Expresso library.
Starting with DynamicExpresso v2.13.0, it's possible to define a variable named "this", that will be used for implicit resolution:
var target = new Interpreter();
target.SetVariable("this", new { FirstName="Homer", LastName="Simpson"});
// 'this' variable is used implicitly
Assert.AreEqual("Homer", target.Eval("FirstName"));
// 'this' variable can also be used explicitly
Assert.AreEqual("Homer", target.Eval("this.FirstName"));

List of DisposableLazy`2 does not have 'Add' method when called using dynamic variable

Problem
I am facing a problem using dynamically created list of items when Add method is called on dynamicvariable. Consider following code.
IEnumerable<dynamic> plugins = (IEnumerable<dynamic>)field.GetValue(instance);
if (plugins == null)
continue;
dynamic filteredPlugins = null;
foreach (var plugin in plugins)
{
if (filteredPlugins == null)
filteredPlugins = Activator
.CreateInstance(typeof(List<>)
.MakeGenericType(plugin.GetType()));
if (/* this condition does not matter*/)
//filteredPlugins.Add(plugin);
filteredPlugins.GetType().GetMethod("Add")
.Invoke(filteredPlugins, new object[] { plugin });
}
And now, the commented line filteredPlugins.Add(plugin) will throw System.Reflection.TargetInvocationException with the message 'object' does not contain a definition for 'Add' when plugin is of type
System.ComponentModel.Composition.ExportServices.DisposableLazy<IPlugin,IMetadata>
but it works completely perfect when pluginis of type
System.Lazy<IPlugin, IMetadata>
When the reflection is used to call Add method on the instance filteredPlugins instance as is done on the next line - everything works fine for any type.
My question is WHY is not Add method found in case of DisposableLazy type.
Background
This code is part of the method that I use in OnImportsSatisfied() method. I am using two kinds of import - which differs only in RequiredCreationPolicy - on has CreationPolicy.NonShared and the other default value of CreationPolicy.Any.
[ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)]
private IEnumerable<Lazy<IPlugin, IMetadata>> plugins = null;
For CreationPolicy.NonShared fields the underlaying type in the plugins is DisposableLazy and for CreationPolicy.Any the underlaying type in the plugins is Lazy.
Edit: As asked in the answer - I am using dynamic variable because IPlugin interface can change everytime this method is called and they do not have to have anything in common.
Edit2: I just found similar question C# dynamic type gotcha, so this can be probably closed as duplicite.
Because System.ComponentModel.Composition.ExportServices.DisposableLazy is a private class, the runtime binder is having trouble believing you have permission to use type, where reflection doesn't care.
Which begs the question why are you using dynamics at all in this case. Since DisposableLazy<IPlugin,IMetadata> public interface is it's subclass Lazy<IPlugin, IMetadata> & IDisposable, shouldn't you just be using a List<Lazy<IPlugin, IMetadata>> for either case?
var plugins = (IEnumerable<Lazy<IPlugin, IMetadata>>)field.GetValue(instance);
if (plugins == null)
continue;
var filteredPlugins = new List<Lazy<IPlugin, IMetadata>>();
foreach (var plugin in plugins)
{
if (/* this condition does not matter*/)
filteredPlugins.Add(plugin);
}
}

How can I set up expectations for event registration on a multimock

I am using RhinoMocks 3.6 and would like to use the multimock feature to implement both a class and a interface.
var mocks = new MockRepository();
var project = mocks.StrictMultiMock(
typeof(Project),
typeof(INotifyCollectionChanged));
using (mocks.Record())
{
((INotifyCollectionChanged)project).CollectionChanged += null;
LastCall.Constraints(Is.NotNull()).Repeat.Any();
}
The LastCall is working though. I get this message :
System.InvalidOperationException : Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
What am I doing wrong here??
Have you actually checked that the Project class has methods you can override as the error message indicates? I'll assume you have. :-)
I'd suggest you switch to using the AAA syntax instead of record/replay as shown here:
I assume you're wanting to know if the class under test reacts the right way when the CollectionChanged event is fired? If that's the case, you can do it something like this:
var project = MockRepository.GenerateMock<Project, INotifyPropertyChanged>();
project.Expect(p => p.SomeMethod())
.Repeat.Any()
.Raise(p => ((INotifyCollectionChanged)p).CollectionChanged += null,p,new NotifyCollectionChangedEventArgs());

Not able to filter WCF methods for dynamically created proxy

Some months back I was working on a project to display the WCF methods and thier parameters in a dropdown. At that time I was creating a proxy using Add Service Reference and hardcoded the service interface in the code.
How can I show all the methods that are available in my WCF in a dropdown
But when I try to create the proxy dynamically to do the same, the below code doesn't work. Please help me to show only the methods that was defined by me.
// Using Dynamic Proxy Factory by Vipul Modi # Microsoft
DynamicProxyFactory factory = new DynamicProxyFactory(txtService.Text);
// endpoints.
string sContract = "";
foreach (ServiceEndpoint endpoint in factory.Endpoints)
{
sContract = endpoint.Contract.Name; //this is the service interface name, IAccountInfoService
}
DynamicProxy proxy = factory.CreateProxy(sContract);
Type proxyType = proxy.ProxyType;
MethodInfo[] methods = proxyType.GetMethods();
foreach (var method in methods)
{
//if (method.GetCustomAttributes(typeof(OperationContractAttribute), true).Length == 0)
// continue;
string methodName = method.Name;
ddlMethods.Items.Add(methodName);
}
The code commented method.GetCustomAttributes(typeof(OperationContractAttribute), true).Length doesn't work. It doesn't show any method. If I comment it out, then the result is all methods and variables. I want to restrict it to only user defined methods.
i dont know anything about DynamicProxyFactory but looking at http://blogs.msdn.com/b/vipulmodi/archive/2006/11/16/dynamic-programming-with-wcf.aspx it makes me think that
1) the proxy doesnt actually emit methods with the attribute. it doesn't seem to have a need to though i suppose you could tweak the code on your own to make that happen.
2) if you just want a list of method names, it seems you can get that from factory.Contracts