The EndToEnd test of my application includes loading the releasedlls by hand.
During testing i always have the following loaded:
- NUnit shadowcopy of n debug assemblies
- Postbuildeventcopy of n release assemblies
Even if i am sure that the two copies are from the same build generation (version) casting of my reflection loading fails.
to give a little bit of context here is some pseudo code:
private HookingHelper globalhooker;
private Tools.ISomething globalmockery;
TestfixtureSetUp(){
globalhooker = new globalhooker();
globalhooker.Loadfrom("c:\postbuildcopy.dll");
globalmockery = Mockrepository.Generate<Tools.ISomething>();
globalhooker.SetViaReflection<Tools.ISomething>("nameofsomething", globalmockery);
}
I have a helper class which uses Loadfrom to get a static inside an assembly. Before i call anything i have to inject a mock.
This mock is created using the shadowcopy of a tools library in debug version since nunit creates it.
The loaded library is the release version, which is important to me since i want to do testing as close to the real environment as possible.
When i try to inject using reflection i have to use FieldInfo SetValue(...) the call looks something like this:
public static void ReplaceFieldPublicStatic<T>(Type type, string fieldname, T obj)
{
FieldInfo field = AssemblyHelper.GetFieldInfoPublicStatic(type, fieldname);
field.SetValue((T)obj, obj);
}
Somethimes the Reflection works and sometimes my types can not be casted into each other.
The error is an ArgumentException generated by FieldInfo SetValue(...) .
When i inercept the exception and investigate the difference between field.FieldType != typeof(T) only the GetHashCode() call gives a different value.
I think there is a little bit of randomness involved.
Can i force the Typecast? Is that even wise?
Is there something i need to do while buildung my projects that i am missing?
Even if i am sure that the two copies are from the same build generation (version) casting of my reflection loading fails.
Yes - if two types have come from two different Assembly objects, they are different types as far as the CLR is concerned. The assemblies could have been loaded from the exact same byte sequences, but they're still distinct assemblies.
Basically you'll need to pick one Assembly to use for each type.
Related
My understanding so far is that Reflection is used to retrieve the names of Types and their members from an assembly via its metadata. I've come across a few examples of Reflection in action identical to the following example.
class Person
{
public string Name {get;set;}
}
static void Main(string[] args)
{
Person person = new Person();
person.Name = "John";
Console.WriteLine(person.GetType().GetProperty("Name").GetValue(person)); //John
person.Name = "Mary";
Console.WriteLine(person.GetType().GetProperty("Name").GetValue(person)); //Mary
}
I understand how Reflection can get names of Types, members, etc. as this is what's stored in an assembly's metadata, but how does Reflection retrieve the value associated with it? This is dynamic data that changes during a program's execution (as shown in the example), which an assembly's metadata doesn't contain (right?).
Would be grateful for clarification on how Reflection retrieves actual values and whether this is actually the case. Please correct anything I've said that's not correct!
The short answer is that reflection is a feature of the runtime, so it has access to runtime information. Were it a separate library with no runtime "hooks", you're right, it wouldn't be able to get the values of properties at runtime, or make calls, or anything else that wouldn't be essentially observable from the assembly file on disk.
Long answer where I prove this to myself:
Microsoft makes available a reference version of the C# source code used to write the base class libraries for .NET Framework. If we look at the PropertyInfo.GetValue(object) method you use in your example, it's defined here. Following the trail of calls we eventually get to an abstract method of the same name but different parameters. Further down in the source file is the implementing class, RuntimePropertyInfo, and its override of GetValue we see that it is implemented by calling the property's get accessor (as, under the hood, properties are just collections of methods with certain signature conventions - GetGetMethod is a funny name meaning "get me the method defined as get for the current property"):
MethodInfo m = GetGetMethod(true);
if (m == null)
throw new ArgumentException(System.Environment.GetResourceString("Arg_GetMethNotFnd"));
return m.Invoke(obj, invokeAttr, binder, index, null);
If we do a similar spelunking journey on MethodInfo.Invoke, we eventually reach RuntimeMethodHandle.InvokeMethod, which is declared:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
The extern keyword on a class means "I don't have the body for this method in C#, look elsewhere for it". For most users of C# this means they're using DllImport to reference native code, but this method has a different attribute: MethodImpl, with the MethodImplOptions.InternalCall enum value. This is the C# way of saying to the compiler, "I don't have the body, but the actual runtime itself does".
So at the end of our journey we reach the point where the Reflection API relies on the runtime itself. Of course, the runtime and the base class libraries have to be developed in tandem to ensure these sync-up points exist.
Interestingly, the actual standard for .NET - ECMA-335 - makes the Reflection API optional, when the implementation (meaning the runtime + base class libraries) adheres to the bare minimum "Kernel Profile" (cite: 6th Ed., §IV.4.1.3). So actually there are implementations of .NET where you're not explicitly allowed to inspect the runtime like this, but given the reliance some kinds of applications have on reflection, all big implementations (original .NET Framework, .NET Core / the new .NET, and Mono) provide it.
The TLDR is the CLR (Common Language Runtime) keeps track of all your objects in memory and when you call GetValue it retrieves the value for you.
Note this post is a little old, but here is a rough idea of what an object looks like in memory:
Please refer to the part that says Object Instance. An object laid out in memory, contains the following 4 items:
Syncblk
TypeHandle
Instance Fields
String Literals
When you call GetValue, using an OBJECTREF to the object instance, it finds the starting location where your instance fields are stored. From there it can figure out which instance to retrieve based on the type.
I believe the actual call is FieldDesc::GetInstanceField.
Using Unity 2018-2017 with same problem on building for net-
error CS0117: 'Delegate' does not contain a definition for 'CreateDelegate'
This is the method:
private V CreateDelegate<V>(MethodInfo method, Object target) where V : class
{
var ret = (Delegate.CreateDelegate(typeof(V), target, method) as V);
if (ret == null)
{
throw new ArgumentException("Unabled to create delegate for method called " + method.Name);
}
return ret;
}
Building for UWP.
Using system.Linq
I tryed with "MethodInfo" but maybe some parameters are wrong.
This method isn´t available?
Which platform/runtime are you targeting? I don't know about Mono, but .Net standard 1.x doesn't support Delegate.CreateDelegate. Always keep in mind that you're writing your code against a limited subset of the .Net framework. Also keep in mind that your code will inevitably be AOT-compiled on some platforms (il2cpp, iOS, etc.), so some reflection/emit features will be unavailable.
Note: AOT means ahead-of-time, meaning your code is compiled to machine instructions rather than an intermediate language. Reflection is when you use the code itself as data, so for example you can get a list of the properties a class defines. Emit means generating code at runtime. If you don't understand what those are, you should probably do some studying. It's well worth the effort in the long run.
1. Your return type is a class, not a delegate.
where V : class
So this method doesn't even make sense. You're going to get an invalid cast exception.
2. CreateDelegate takes 2 parameters, not 3.
I'm not even sure what purpose target even serves here, so I can't even guess what you're trying to do.
Assume I have 2 dlls maintained by 2 different teams:
Team1.dll (v1.0)
public class Foo
{
int GetValue() { return 3; }
}
Team2.dll (v1.0)
public class Bar
{
public int IncFooValue(Foo foo) { return foo.GetValue() + 1; }
}
When Team1.dll (v1.0) and Team2.dll (v1.0) are executed, everything is fine. But assume that Team1.dll were changed & the method Foo.GetValue() were removed (v1.1) and dropped next to Team2.dll (all without rebuilding Team2.dll). If executed, then you would get a MissingMethodException.
Question: How could I detect if Team1.dll is no longer compatible with Team2.dll without executing them?
For example, something like:
Foreach Class in Team2.dll
Foreach Method in Class
Foreach Instruction in Method
If Instruction not exists in Team1.dll
Throw "Does not exist"
It is possible to detect missing methods by forcing JIT compilation of your methods.
For that you just need enumerate all methods in your assemblies using reflection and then call RuntimeHelpers.PrepareMethod(method.MethodHandle) for each of them.
The tricky part here is dealing with generics. If your method or class contains generics, you also need to specify the concrete types for which your generic method will be jitted:
Type[] classGenericArgs = ...;
Type[] methodGenericArgs = ...;
Type[] allGenericArgs = classGenericArgs.Concat(methodGenericArgs).ToArray();
RuntimeHelpers.PrepareMethod(method.MethodHandle, allGenericArgs.Select(p => p.TypeHandle).ToArray());`
If your generic arguments also have constraints, you need to make sure that the types you choose satisfy these constraints, otherwise, jitting will fail.
Satisfying constraints can be difficult, so I wrote a Jitter class to automate this. It forces load of all libraries referenced by your application into memory and runs jitting with automatically substituting appropriate concrete classes for your generic methods (if possible). The usage for it is simple, just specify which assemblies you want jitted:
Jitter.RunJitting(asm => asm.FullName.StartsWith("My.Company.Namespace"));
Make sure your .NET app references all assemblies you want to verify.
You can find the source code for Jitter here. It is far from perfect, but is able to jit 99.8% of all methods in our codebase and detect broken package dependencies for us.
Check if the type contains the definition of the method.
if (foo.GetType().GetMethod("GetValue") != null)
{
return foo.GetValue() + 1;
}
as others have suggested you may be better off pursuing another strategy (better versioning/backwards compatibility or handling the exception on the calling end.
I need to cache results from heavy calculations done by several different classes inheriting from the same base class. I was doing run-time caching by subclass name. Now I need to store the results on disk/DB to avoid long recalculations when I restart my app, but I need to invalidate cache if I change the code inside Calculate().
type BaseCalculator() =
let output = ConcurrentDictionary<string, Series<DateTime, float>>() // has public getter, the output is cached by the caller of Calculate() method
abstract Calculate: unit->unit
type FirstCalculator() =
inherit BaseCalculator()
override this.Calculate() = ... do heavy work here ...
From this question and answers I have learned that I could use [<ReflectedDefinition>] on my calculate method. But I have never worked with quotations myself before.
The questions are:
Could I use a hash code of quotations to uniquely identify the body of the method, or there are some guids or timestamps inside quotations?
Could [<ReflectedDefinition>] be applied to the abstract method and will it work if I override the method in C#, but call the method from F# runner? (I use reflection to load all implementations of the base class in all dlls in a folder)
Is there other simple and reliable method to detect code changes in an assembly automatically, without quotations? Using last modified time of an assembly file (dll) could work, but any change in an assembly will invalidate all calculators in the assembly. This could work if I separate stable and WIP calculators into separate assemblies, but more granularity is preferred.
Could I use a hash code of quotations to uniquely identify the body of the method, or there are some guids or timestamps inside quotations?
I think this would work. Have a look at FsPickler (which is used by MBrace to serialize quotations). I think it can give you a hash of a quotation too. But keep in mind that other parts of your code might change (e.g. another method in another type).
Could ReflectedDefinition be applied to the abstract method and will it work if I override the method in C#, but call the method from F# runner?
No, the attribute only works on F# methods compiled using the F# compiler.
Is there other simple and reliable method to detect code changes in an assembly automatically, without quotations?
I'm not sure. You could use GetMethodBody method and .NET reflection to get the IL, but this only gives you the immediate body - not including e.g. lambda functions, so changes that happen elsewhere will not be easy to detect.
A completely different approach that might work better would be to keep the calculations in FSX files in plain text and compile them on the fly using F# Compiler Service. Then you could just hash the source of the individual FSX files (on a per-computation basis).
I have found that Mono.Cecil is surprisingly easy to use, and with it I could hash all member bodies of a type, including base type.
This SO question was very helpful as a starting point.
Looking through System.Linq.Enumerable in DotPeek I notice that some methods are flavoured with a [__DynamicallyInvokable] attribute.
What role does this attribute play? Is it something added by DotPeek or does it play another role, perhaps informing the compiler on how best to optimise the methods?
It is undocumented, but it looks like one of the optimizations in .NET 4.5. It appears to be used to prime the reflection type info cache, making subsequent reflection code on common framework types run faster. There's a comment about it in the Reference Source for System.Reflection.Assembly.cs, RuntimeAssembly.Flags property:
// Each blessed API will be annotated with a "__DynamicallyInvokableAttribute".
// This "__DynamicallyInvokableAttribute" is a type defined in its own assembly.
// So the ctor is always a MethodDef and the type a TypeDef.
// We cache this ctor MethodDef token for faster custom attribute lookup.
// If this attribute type doesn't exist in the assembly, it means the assembly
// doesn't contain any blessed APIs.
Type invocableAttribute = GetType("__DynamicallyInvokableAttribute", false);
if (invocableAttribute != null)
{
Contract.Assert(((MetadataToken)invocableAttribute.MetadataToken).IsTypeDef);
ConstructorInfo ctor = invocableAttribute.GetConstructor(Type.EmptyTypes);
Contract.Assert(ctor != null);
int token = ctor.MetadataToken;
Contract.Assert(((MetadataToken)token).IsMethodDef);
flags |= (ASSEMBLY_FLAGS)token & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK;
}
Without further hints what a "blessed API" might mean. Although it is clear from the context that this will only work on types in the framework itself. There ought to be additional code somewhere that checks the attribute applied to types and methods. No idea where that is located, but given that it would have to need to have a view of all .NET types to have a shot at caching, I can only think of Ngen.exe.
I found that it's used in the Runtime*Info.IsNonW8PFrameworkAPI() suite of internal methods. Having this attribute placed on a member makes IsNonW8PFrameworkAPI() return false for it and thus makes the member available in WinRT applications and shuts up the The API '...' cannot be used on the current platform. exception.
Profiler writers should place this attribute on members emitted by their profiler into framework assemblies, if they want to access them under WinRT.
sorry if I answer late. This attribute is used to call unmanaged code function from managed code. It is used to separate the managed language from the unmanaged language. a barrier of two worlds. It is also used for security reasons. to make unmanaged code reflection inaccessible.