I know you cant override or inherit from a static class and why. That is clear.
I am looking for some advice on how to replace that static class with my own static class. Any hackish or wildest attempts please.
I am basically writing a MOD for a game and the way the game writer wrote one class in particular, he set it as static and put the implementation in there. So when we write our own DLL with this thing, the only way to execute a calculation on the pixel grid is when his code calls this particular calculation in his static class. Both classes are static but I only need to change one.
That is great for him but I want my thing to do another calculation and make it more awesome. I used ILspy and can see all the code in that static class of the base game, so I can copy and paste it and I only need to modify two or three lines.
But now I want to nuke the games core static class and make mine the only implementation.
I want to force replace that static class at runtime, before the static class is ever called and after loading my mod, how? There must be a way to swap static classes?
I read about creating a proxy DLL that redirects all methods to the old DLL and my method to my DLL but that would require gamers to replace a core game DLL and that is even dirtier than just telling people what my mod does. I am changing thas implementation for this mod, if you dont like don use my mod. That is more reasonable.
I will assume you don't have access to the source and thus can't modify it directly.
You COULD (probably shouldn't) use microsoft fakes since it is mainly for testing. You could create a fakes assembly based on the original author's dll, and override just the type you want. It even supports overriding static classes. Again, I am not saying that you necessarily SHOULD do this, but you COULD.
Here is the page for isolating code under test, it includes an example for shimming a static class (DateTime) https://msdn.microsoft.com/en-us/library/hh549175.aspx
A few options ...
Review how the original developer said to modify the game
You could use something like JustDecompile to get their code.
Use Fakes as suggested above
Create your own assembly that calls into their assembly and hack the IL dynamically
This seems pretty close to this question: Can I redirect .NET method calls to a new method at runtime?
One of the answers to this post suggests looking at a library called Moles which seems to be similar to Detours and may help
Moles allows to replace any .NET method with a delegate. Moles supports static or non-virtual methods
Related
I have some DLL from third party that I need to license. It has some method that I must call from my own DLL. My DLL is referenced in couple of projects and I don't want to make changes to every hoster. Is there any method that I can use within my DLL which will call some method in my DLL? Like add some static class or constructor but without explicit call to that class from hosters? I am not sure if I am explaining it clearly. Please ask questions if needed.
ThirdPartyType license = new ThirdPartyType();
license.Load("license.xml");
This is a piece of licensing code that I want to place in my DLL and call it within the same DLL.
At the low level, the runtime supports "module initializers". However, C# does not provide any way of implementing them, so the closest you can manage is a static constructor ("type initializer") or just a regular constructor.
However, it is probably a bad idea to hook your licencing into either a module initializer or a type initializer, as you don't know when they will run, and it could impact code that wasn't going to access your lib. It is somewhat frowned upon to take someone's app down because your licensing code decided it was unhappy - especially if your library wasn't actively being invoked at the time.
As such: I suggest the most appropriate place to do this is in either a constructor, or a post-construction Initialize(...) method (with the tool refusing to work unless supplied with valid details).
I'm working on a collection of code where there's most of the functionality in a PCL. I want to init members like
class CentralInPCL {
public static Func<string> DefaultPathProvider;
This needs to be assigned a lambda () => Path.GetTempFileName() from an assembly built for one of the platforms.
How do I reliably assign this lambda in another assembly?
Can I guarantee a static constructor of a helper class, in another assembly, will be run before any instances of CentralInPCL might be used?
I may have completely mis-understood something about how a PCL works but we're trying to avoid having user code have to pass parameters to the PCL.
As I understand them, a PCL is a leaf library called by platform-specific assemblies.
You would normally give it access to platform stuff by injecting an object or lambda, typically confirming to an interface defined in the PCL.
However, that injection process is explicit and has to be out there in some platform-specific code, usually user code.
I'm trying to add a bit more magic and have some defaults injected without the user knowing.
An old 2005 answer from Jon Skeet suggests you couldn't do it, at least back then.
I found a recipe for doing it with Fody, weaving in a Module Initializer which is an IL thing not able to be declared in C#.
Failing which, we need to require the user to include a call to setup static defaults somewhere.
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'm trying to do something rather... unique, and maybe there's a far better way to do it but... I'm doing an inversion of control(ish) system that uses extension methods to enable/disable components of the class, so before I get into more detail and confuse you, lets look at some code!
using TestComponents.CommunicationProtocols.RS232;
//this brings in the
//ConnectRS232 extension method
namespace TestMeNamespace
{
public class Test //Although this class is defined here, we extend it above
{
public void Start()
{
this.ConnectRS232(1, 9600); //calls the ConnectRS232 extension method
}
}
}
So in short, the using declaration extends Test in the same file that we DEFINE test.
(inheritance would be fine as well) However there are some problems with this! first of all, the ugly requisite "this". blech. secondly it's a messy co-dependant system.
Here's what I'm attempting to achieve:
I want a way to easily extend static methods to a class (using declarations are fine)
I want to make statements simple: ConnectRS232();
I want to not have to futz with partial classes if I don't have to.
I'd be fine with using interface inheritance.
Feel free to ask me additional questions via comments but please don't post an answer unless you have an ANSWER!
Edit: In lieu of questions raised, I'm doing some JIT compilation of C#script (www.cs-script.com) in my system, and also these scripts will be mostly written by non-programmers who have been using a really "special" proprietary language for scripting for years. I want to keep things simple as hell, and a whole bunch of "this" calls look like clutter.
I'm not sure I see the point in this...
Your "extensions" will be compile time only. The extension methods only work as static methods, and since you're building this on importing of namespaces, it's more of a compile time construct than any form of IoC. (Extension methods are just a compile time thing - they don't really do anything at runtime.)
Also, given the above statement, having this.Method() doesn't seem onerous (it's good practice to use normally, which is why tools such as StyleCop enforce that you do that on EVERY method call).
Can you give us a better example of how this would be used? Right now, it just seems like a way to put code in two places instead of one, with no real benefit...
As the Title says, I've got a multi-project solution.
I've got a "core" project that is loaded with most of the other projects.
So my question is this, I have a few utility functions such as FormatPhoneNumber(..) that I would like to be able to access in the following manner from anywhere.
(in Project_B which depends on Core)
string str = FormatPhoneNumber(inputString);
At worst, I suppose I could live with a qualifier of some sort:
string str = util.FormatPhoneNumber(inputString);
The best way of doing this is to create a dll project (maybe called something like "CommonCode"?), that you can then reference this dll from all of your other projects and access the classes and methods therein.
You will have to have some sort of "qualifier" (as you call it) somewhere, but to reduce the impact use the using statement at the top of each file, e.g.
using util;
If you really must have such utility functions (you know, you shouldn't, but sometimes it's the best/easiest solution), I suggest having them either in the Core (assuming that every single project is dependent on the Core anyway), or in a separate utility assembly. If you don't want to have a separate assembly lying around, consider using ILMerge.
The qualifier should be no problem at all. I suggest not putting unrelated function into an Utils class, but rather use e.g. a Formatting class for all formatting functions. On the other hand, as s_ruchit in the meantime suggested, extension methods (e.g. for the string class) might come in handy as well.
(Did I mention that this ยง%$& MarkDown editor does not allow typing an [at] symbol on a German keyboard layout, because it instead creates a blockquote? Sigh.)
Try creating your own util library.
Create a Class Library project and put your util classes in there.
I myself try to adhere a naming convention like [companyName].Util.[subdomain]
Your example would probably fit in my [CompanyName].Utils.StringHelpers
You would then create a static class StringHelper with a static method FormatPhoneNumber.
You will see that these personal libraries quickly grow bigger. By grouping them you don't have to load all your code if you only need a subset of functions.
Use an extension method to make it easier to call the method without using the class name.
public static class Util {
public static string FormatPhoneNumber(this string input) {
:
}
}
The method will now appear on every string object. You do not need to know which class it comes from. However, if the extension class is declared in another namespace, you must still import the namespace.
string formattedString = inputString.FormatPhoneNumber();
If you are using C# 3.0, you can bind them all into one single static class use them as Extension Methods.
There are no global functions in .NET, so you will have to put your utility functions into a class. You can make the methods static, so you can call them without having to instantiate the utility class:
public class Utility
{
public static string FormatPhoneNumber(string input)
{
...
}
}
// usage:
string output = Utility.FormatPhoneNumber(input);
Put these methods into your core library or a separate utility library that can be used (referenced) by all other libraries and applications.
You need to put the functions in static classes. You cannot avoid the qualification (there are no global functions in C#):
<%= Formatters.PhoneNumber(rawData) %>
The utility functions should be grouped as per normal methods: similar methods go together, unrelated methods should go into different classes (event with static classes aim for low coupling and high cohesion).
The assembly each belongs in should be obvious: formatting functions only used by the presentation layer (ASP.NET project itself) belong there. Truly common functions could go into core.
If the function you are implementing can only be used in context of your application, i would recommend you to place it into the Core assembly (under a separate namespace like "Utils" for example) or a new DLL library of your application solution.
Only if the function can be used across multiple projects it makes sense to create a utility library. But always keep in mind that a utility library only make sense if it's maintained regularly.
If you want all code to access these methods then go with extension methods, otherwise I would go with Util class in core assembly.
FWIW, if you follow a more formalised namespace as boris sugguests (recommended to avoid conflicts) you can abbreviate with the using keyword:
using Util = [CompanyName].Utils.StringHelpers;
I tend to follow the DRY principle and create an alias as soon as I need it more than once.