Let’s say that I have two C# applications - game.exe (XNA, needs to support Xbox 360) and editor.exe (XNA hosted in WinForms) - they both share an engine.dll assembly that does the vast majority of the work.
Now let’s say that I want to add some kind of C#-based scripting (it’s not quite "scripting" but I’ll call it that). Each level gets its own class inherited from a base class (we’ll call it LevelController).
These are the important constraints for these scripts:
They need to be real, compiled C# code
They should require minimal manual "glue" work, if any
They must run in the same AppDomain as everything else
For the game - this is pretty straight forward: All the script classes can be compiled into an assembly (say, levels.dll) and the individual classes can be instanced using reflection as needed.
The editor is much harder. The editor has the ability to "play the game" within the editor window, and then reset everything back to where it started (which is why the editor needs to know about these scripts in the first place).
What I am trying to achieve is basically a "reload script" button in the editor that will recompile and load the script class associated with the level being edited and, when the user presses the "play" button, create an instance of the most recently compiled script.
The upshot of which will be a rapid edit-test workflow within the editor (instead of the alternative - which is to save the level, close the editor, recompile the solution, launch the editor, load the level, test).
Now I think I have worked out a potential way to achieve this - which itself leads to a number of questions (given below):
Compile the collection of .cs files required for a given level (or, if need be, the whole levels.dll project) into a temporary, unique-named assembly. That assembly will need to reference engine.dll. How to invoke the compiler this way at runtime? How to get it to output such an assembly (and can I do it in memory)?
Load the new assembly. Will it matter that I am loading classes with the same name into the same process? (I am under the impression that the names are qualified by assembly name?)
Now, as I mentioned, I can’t use AppDomains. But, on the other hand, I don’t mind leaking old versions of script classes, so the ability to unload isn’t important. Unless it is? I’m assuming that loading maybe a few hundred assemblies is feasible.
When playing the level, instance the class that is inherited from LevelController from the specific assembly that was just loaded. How to do this?
And finally:
Is this a sensible approach? Could it be done a better way?
UPDATE: These days I use a far simpler approach to solve the underlying problem.
There is now a rather elegant solution, made possible by (a) a new feature in .NET 4.0, and (b) Roslyn.
Collectible Assemblies
In .NET 4.0, you can specify AssemblyBuilderAccess.RunAndCollect when defining a dynamic assembly, which makes the dynamic assembly garbage collectible:
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("Foo"), AssemblyBuilderAccess.RunAndCollect);
With vanilla .NET 4.0, I think that you need to populate the dynamic assembly by writing methods in raw IL.
Roslyn
Enter Roslyn: Roslyn lets you compile raw C# code into a dynamic assembly. Here's an example, inspired by these two blog posts, updated to work with the latest Roslyn binaries:
using System;
using System.Reflection;
using System.Reflection.Emit;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
namespace ConsoleApplication1
{
public static class Program
{
private static Type CreateType()
{
SyntaxTree tree = SyntaxTree.ParseText(
#"using System;
namespace Foo
{
public class Bar
{
public static void Test()
{
Console.WriteLine(""Hello World!"");
}
}
}");
var compilation = Compilation.Create("Hello")
.WithOptions(new CompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(MetadataReference.CreateAssemblyReference("mscorlib"))
.AddSyntaxTrees(tree);
ModuleBuilder helloModuleBuilder = AppDomain.CurrentDomain
.DefineDynamicAssembly(new AssemblyName("FooAssembly"), AssemblyBuilderAccess.RunAndCollect)
.DefineDynamicModule("FooModule");
var result = compilation.Emit(helloModuleBuilder);
return helloModuleBuilder.GetType("Foo.Bar");
}
static void Main(string[] args)
{
Type fooType = CreateType();
MethodInfo testMethod = fooType.GetMethod("Test");
testMethod.Invoke(null, null);
WeakReference weak = new WeakReference(fooType);
fooType = null;
testMethod = null;
Console.WriteLine("type = " + weak.Target);
GC.Collect();
Console.WriteLine("type = " + weak.Target);
Console.ReadKey();
}
}
}
In summary: with collectible assemblies and Roslyn, you can compile C# code into an assembly that can be loaded into an AppDomain, and then garbage collected (subject to a number of rules).
Check out the namespaces around Microsoft.CSharp.CSharpCodeProvider and System.CodeDom.Compiler.
Compile the collection of .cs files
Should be pretty straightforward like http://support.microsoft.com/kb/304655
Will it matter that I am loading classes with the same name into the same process?
Not at all. It's just names.
instance the class that is inherited from LevelController.
Load the assembly that you created something like Assembly.Load etc. Query the type you want to instanciate using reflection. Get the constructor and call it.
Well, you want to be able to edit things on the fly, right? that's your goal here isn't it?
When you compile assemblies and load them there's now way to unload them unless you unload your AppDomain.
You can load pre-compiled assemblies with the Assembly.Load method and then invoke the entry point through reflection.
I would consider the dynamic assembly approach. Where you through your current AppDomain say that you want to create a dynamic assembly. This is how the DLR (dynamic language runtime) works. With dynamic assemblies you can create types that implement some visible interface and call them through that. The back side of working with dynamic assemblies is that you have to provide correct IL yourself, you can't simply generate that with the built in .NET compiler, however, I bet the Mono project has a C# compiler implementation you might wanna check out. They already have a C# interpreter which reads in a C# source file and compiles that and executes it, and that's definitely handled through the System.Reflection.Emit API.
I'm not sure about the garbage collection here though, because when it comes to dynamic types I think the runtime doesn't release them because they can be referenced at any time. Only if the dynamic assembly itself is destroyed and no references exist to that assembly would it be reasonable to free that memory. If you're and re-generating a lot of code make sure that the memory is, at some point, collected by the GC.
If the language was Java the answer would be to use JRebel. Since it isn't, the answer is to raise enough noise to show there's demand for this. It might require some sort of alternate CLR or 'c# engine project template' and VS IDE working in coordination etc.
I doubt there's a lot of scenarios where this is "must have" but there's many in which it would save lot of time as you could get away with less infrastructure and quicker turnaround for things that aren't going to be used for long. (Yeah there's some who argue to over-engineer things because they'll be used 20+ years but the problem with that is when you need to do some massive change, it'll likely be as expensive as rebuilding the whole thing from scratch. So it comes down to whether to spend money now or later. Since it's not know for sure the project will become business critical later and might require large changes later anyhow, the argument to me is to use "KISS"-principle and have the complexities of live-editing in the IDE,CLR/runtime and so forth instead of building it into each app where it might be useful later. Certainly some defensive programming and practises will be needed to modify some live service using this sort of feature. As Erlang devs are said to be doing)
Related
I am not even sure if this is possible so apologies if not. I have googled quite extensively and not found what I am looking for.
Basically we have an application produced by a third party, which, to be perfectly blunt is rubbish. We have a particular issue and have managed to trace the problem using ILSpy to a method within a DLL. Obviously we don't have (nor are able to get) the source code and the company in question is unwilling to fix the problem in any reasonable timescales.
So, we've investigated various avenues of investigation and come up with nothing. I've been looking into seeing whether this can be done using reflection and this is pretty much the last hope we have of getting this to work. In a nutshell, what I would like to do is the following:
Create a simple class library with the same name as the existing DLL
Use reflection to import the methods from the existing DLL
Somehow override the method in question with my own, correct code
Rebuild the code, so I have a new DLL, containing 99% of the functionality of the existing DLL but with my override code providing the correct functionality.
I have found, during my investigations TypeBuilder.DefineMethodOverride and also a page from StackOverflow, which seems similar but not quite what I am looking for.
http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx
Is there a way to "override" a method with reflection?
Any advice appreciated!
Andrew
Edit
The other possible idea I has was to produce a partial class containing the override function, but that didn't seem feasible either.
You can override the method only if it is virtual, and it doesn't matter whether you do it through reflection or statically. I would suggest using a decompiler (there are a lot of free ones available) and fixing the code in MSIL. Then you can generate a new assembly from the MSIL.
I think your first idea is good.
If the third party class isn't sealed, you can derive from it, and add your own method, with a different name, to correct the behavior that is wrong.
If you need it to be in 1 dll, you can use IlMerge.
If your third party class is sealed you can just have an instance of this third party class in your new class and call the methods when needed.
But you'll have to check that the method you want to "override" isn't called inside that library, because if it is this solution won't work...
It's not very clean, but it can be a temporary solution during the time the company that edits the library fixes the problem.
And when it's fixed you'd just have to rename the method you use, so it won't be time consuming.
From what you have described I would recommend modifying the original assembly. The process is essentially
Decompile the assembly into MSIL, C# or whatever language you so choose
Modify the decompiled assembly to include your changes
Recompile the assembly using the modified source
From what I can see Reflexil allows you to do just that, although it may require that you buy Resharper (I've not tried it myself)
Alternatively you can use ILDasm to decompile the entire assembly to a single file, modify the file and then recompile it using ILAsm
I know I'm coming in a bit late on this, but I'd agree with Charleh; if you've got a class that's not behaving well and isn't conducive to substitution, but at least declares its methods as virtual, then you're in luck. The following uses references to Castle.Core and Patterns:
var interceptor = new DelegateInterceptor(proceed: call =>
{
if(ShouldCallProceed(call)) call.Proceed();
else AlternativeLogic();
});
var generator = new ProxyGenerator();
var proxy = generator.CreateClassProxy<UncooperativeType>(interceptor);
proxy.RubbishMethod();
I've also taken the liberty of providing a running sample of this in LinqPad. It shows the difference between methods that allow interception (virtual ones) and ones that don't. It also shows a useful way of trapping exceptions without all the code using Try.Do from Patterns.
I need to use a iOS build setting in Unity3d that strips unused classes from bytecode but as it uses static analysis to discover which to remove- so any classes resolved through reflection will not be excluded from removal unless explicitly added to an exclusion list. I managed to remove all uses of reflection in my own code, but Mono itself seems to use a reflection based configuration to do a bunch of stuff and I've already added about a dozen classes to the exclusion list but now I'm to the point where exceptions are not giving any clues as to what class needs to be excluded for them to work.
My question is, is it possible to get a precise list of all the classes (with source assembly and namespace) resolved through reflection throughout every assembly that the application uses, and how would you go about it? I have Visual Studio 2012 and while I know it has powerful debugging tools I don't know how I would use them to this end.
Thanks.
The short version
You can't as there is no way to find all lookups via reflection using static analysis.
The long version
Just think of the following example: I write code that selects a class depending on user input, e.g. in pseudo code:
string action = ... ; // get some user input here, e.g. "Fire"
string clazz = "Do" + action;
var obj = Activator.CreateInstance("MyActions", clazz);
As you can see the actual full class name is not occuring anywhere in the code. So you would need to execute the code in every possible way to find out which values the clazz variable could assume. Therefore you cannot find out which classes this code would access via reflection.
Further Questions
What exact API from Mono are you using and what kind of exceptions are you getting? Maybe there is some alternative that could be used for your purpose.
I just finished watching an episode of Bob Martin at NDC where he said "using" directives in C# at the top of a page are bad because of the tight coupling they create/imply between components.
What way are there to use external .dlls without adding a project reference and a using statement?
I remember V6 used to let you create an object by the string of the ProgId--I'm not sure that's the technique I'm looking for, but it's an example of a language that didn't need a project reference to use a dll.
EDIT: Here is a link to the conference. Sorry I don't have the exact quote or minute in the presenation, I'm going by memory.
I believe Bob Martin is actually referring to early versus late binding.
In .NET late binding is possible through reflection and more specifically the Activator class that allows creation of a type in an external assembly using a filename or assembly name.
Normally, using directives (not the using statement) go hand in hand with directly referencing an external assembly. ie. You add a reference to an assembly and then add using directives to avoid needing to type the full namespace hierarchy when you use the external types.
So if you find your code has a large number of using directives at the top, it is possible that you are referencing many other types directly and so increasing the coupling/dependency of your code on these types.
I would guess this is why Bob is referring to them as bad. The answer to the question "is this actually bad?" is a very subjective and context dependent one.
In general though, de-coupling of components is almost always a good goal to aim for in designing software. This is because it allows you to change parts of your system with minimal impact on the rest of the system. Having read one or two of Bob Martins books, I would expect this is what he is getting at.
It's not the using statement itself that is bad - it's if you get too many of them.
A statement such as using System; is rarely a problem in itself, but if you have lots (I'd say more than 3-6, depending on which ones) in the same code file, it could be an indication of tight coupling.
You could just as well apply a similar rule of thumb to the number of references in a project itself.
The solution to tight coupling is programming to interfaces and Dependency Injection (DI).
The ProgId way of doing things that you can remember from VB was simply COM in action. In essence, you used that ProgId to get a reference to an instance that implemented the desired interface. The downside was that this only worked when the COM object was universally registered. Remember dll hell?
You can still apply the same principle using certain flavors of DI, only that now the interface is a .NET type and not defined in IDL, and you need some sort of DI Container to supply the concrete implementation.
using is just a shortcut to namespaces, they are not references to external files. Therefore, this is just not really making sense.
Anyways, what one can do is have an interface DLL (a DLL with only interfaces), so that you dynamically load and use different assemblies and create types (through reflection) which you can cast to the well-known interfaces. This is the proper way of loosening external references while keeping the benefits of the strongly typed language and early binding.
Have a look at the Assembly and AppDomain classes to load assemblies, and Activator to create type instances by name.
You could use reflection:
// Load the assembly
Assembly assembly = Assembly.LoadFrom(#"c:\path\Tools.dll");
// Select a type
Type type = assembly.GetType("Tools.Utility");
// invoke a method on this type
type.InvokeMember("SomeMethod", BindingFlags.Static, null, null, new object[0]);
You can do what you are referring to through reflection. You can load the assembly at runtime, and reflect through it to get the classes etc. and call them dynamically.
Personally, I wouldn't do this though to avoid coupling. To me that is a bad use of reflection, and I would much rather add it to the project and reference it, unless there is a specific reason why not to do so. Reflection adds overhead to the system, and you don't get the advantage of compile time safety.
Due to politics at the very large finanial institution for which I work, I am not able to use Castle Project's ActiveRecord implementation, but like the pattern so much I have implemented it myself. This is complete, and now management is looking for a GUI tool to browse all the activerecord classes, search for instances and manage data.
To this end, I'm building a "browser" that iterates through all the classes in a referenced project, and if they are derived from a partiular base class ("ActiveInstanceBase"), make them available for inspection and modification in an ASP.net datagrid.
The first step for me is to figure out how to iterate through all the references in the current project (developers using this tool will add their dlls to the project as references) and identify the ActiveInstance classes in order to fill a dropdown full of types to inspect.
How do I get a list of all the references for a current project? Google is not turning anything up for me on the first page of results for a number of queries. I'm getting a lot of stuff about writing Visual Studio addins, but nothing for runtime inspection.
How do I determine the base class of a derived type at runtime if the base class takes a Type parameter?
if (t.IsSubclassOf(typeof(ActiveInstance.ActiveInstanceBase)))
{}
Isn't the proper syntax, and I can't know t at runtime.
I'm also forced to use IE6, so pardon if this post is not very well-formatted. Thanks very much in advance!
1) How to get the assemblies referenced in your project
Assembly ourAssembly = Assembly.GetEntryAssembly();
AssemblyName[] refs = ourAssembly.GetReferencedAssemblies();
2) Use Type.IsSubclassOf() or Type.GetInterface()
Type theType = typeof(ActiveInstance.ActiveInstanceBase<>);
foreach(Type type in assembly.GetTypes())
{
if (type.IsSubclassOf(theType))
{ ... }
}
Those should work for you...
if you have political rules against downloading third party software, this may not work, but I use .net Reflector. It will give you the references and decompile the code for reviewing.
http://www.red-gate.com/products/reflector/
I have wondered about the appropriateness of reflection in C# code. For example I have written a function which iterates through the properties of a given source object and creates a new instance of a specified type, then copies the values of properties with the same name from one to the other. I created this to copy data from one auto-generated LINQ object to another in order to get around the lack of inheritance from multiple tables in LINQ.
However, I can't help but think code like this is really 'cheating', i.e. rather than using using the provided language constructs to achieve a given end it allows you to circumvent them.
To what degree is this sort of code acceptable? What are the risks? What are legitimate uses of this approach?
Sometimes using reflection can be a bit of a hack, but a lot of the time it's simply the most fantastic code tool.
Look at the .Net property grid - anyone who's used Visual Studio will be familiar with it. You can point it at any object and it it will produce a simple property editor. That uses reflection, in fact most of VS's toolbox does.
Look at unit tests - they're loaded by reflection (at least in NUnit and MSTest).
Reflection allows dynamic-style behaviour from static languages.
The one thing it really needs is duck typing - the C# compiler already supports this: you can foreach anything that looks like IEnumerable, whether it implements the interface or not. You can use the C#3 collection syntax on any class that has a method called Add.
Use reflection wherever you need dynamic-style behaviour - for instance you have a collection of objects and you want to check the same property on each.
The risks are similar for dynamic types - compile time exceptions become run time ones. You code is not as 'safe' and you have to react accordingly.
The .Net reflection code is very quick, but not as fast as the explicit call would have been.
I agree, it gives me the it works but it feels like a hack feeling. I try to avoid reflection whenever possible. I have been burned many times after refactoring code which had reflection in it. Code compiles fine, tests even run, but under special circumstances (which the tests didn't cover) the program blows up run-time because of my refactoring in one of the objects the reflection code poked into.
Example 1: Reflection in OR mapper, you change the name or the type of the property in your object model: Blows up run-time.
Example 2: You are in a SOA shop. Web Services are complete decoupled (or so you think). They have their own set of generated proxy classes, but in the mapping you decide to save some time and you do this:
ExternalColor c = (ExternalColor)Enum.Parse(typeof(ExternalColor),
internalColor.ToString());
Under the covers this is also reflection but done by the .net framework itself. Now what happens if you decide to rename InternalColor.Grey to InternalColor.Gray? Everything looks ok, it builds fine, and even runs fine.. until the day some stupid user decides to use the color Gray... at which point the mapper will blow up.
Reflection is a wonderful tool that I could not live without. It can make programming much easier and faster.
For instance, I use reflection in my ORM layer to be able to assign properties with column values from tables. If it wasn't for reflection I have had to create a copy class for each table/class mapping.
As for the external color exception above. The problem is not Enum.Parse, but that the coder didnt not catch the proper exception. Since a string is parsed, the coder should always assume that the string can contain an incorrect value.
The same problem applies to all advanced programming in .Net. "With great power, comes great responsibility". Using reflection gives you much power. But make sure that you know how to use it properly. There are dozens of examples on the web.
It may be just me, but the way I'd get into this is by creating a code generator - using reflection at runtime is a bit costly and untyped. Creating classes that would get generated according to your latest code and copy everything in a strongly typed manner would mean that you will catch these errors at build-time.
For instance, a generated class may look like this:
static class AtoBCopier
{
public static B Copy(A item)
{
return new B() { Prop1 = item.Prop1, Prop2 = item.Prop2 };
}
}
If either class doesn't have the properties or their types change, the code doesn't compile. Plus, there's a huge improvement in times.
I recently used reflection in C# for finding implementations of a specific interface. I had written a simple batch-style interpreter that looked up "actions" for each step of the computation based on the class name. Reflecting the current namespace then pops up the right implementation of my IStep inteface that can be Execute()ed. This way, adding new "actions" is as easy as creating a new derived class - no need to add it to a registry, or even worse: forgetting to add it to a registry...
Reflection makes it very easy to implement plugin architectures where plugin DLLs are automatically loaded at runtime (not explicitly linked at compile time).
These can be scanned for classes that implement/extend relevant interfaces/classes. Reflection can then be used to instantiate instances of these on demand.