I have a dll where I have one class which logs to a "channel", another Program listens to the "channel" and writes the logs to the screen. The problem with the dll is that its grown over time and now there are many dependecies in it. I want to remove the logging part from this dll and place it in a debugging and logging dll.
The problem is that the debugging and logging dll has another namespace which I want to use in the class or rather I want to use the class in the namespace. My problem with this is that some developers used the namespace nearly exclusively when calling the methods instead of using it in the top of their classes.
It looks like the following for a static method:
Base.Manager.Logging.Send("Log something");
The other Dll has the simple namespace Trace so it should look like this:
Trace.Logging.Send("Log something");
My question is, is there an elegant way to move the class and change the namespace without altering all the uses of the Methods ? I could simply copy the class to the other dll and then use the old class as a wrapper which forwards all the calls to the other class in the Trace.dll but this approach seems a little bit hacky.
I hope this grafik illustrates what I mean because I think the simple text may be somewhat confusing
FYI: I don't have ReSharper
Unfortunately you can't. If you keep same namespace then you can use
TypeForwardAttribute
but if you also change namespace (not just assembly) then it doesn't work.What I suggest is to move it to new class, keep old class to don't break code both at run-time & compile-time and forward all calls. Mark all old methods as obsolete (at least they'll be warned that code will change in future). Just to clarify:
Step 1: empty your old deprecated class and forward calls to new class. Mark old methods as obsolete.
Will then be refactored to:
It'll generate a warning (with given message) during compilation. Compile-time compatibility is saved. Note we also added
EditorBrowsableAttribute
, IntelliSense won't propose thatLogger
class when they start typing. This reduces (little bit) chances they will still useBase.Manager.Logger
for new code.Step 2: someday in future you'll change that warning to an error:
This will break compilation but it'll preserve binaries compatibility. Other DLLs will still run (so you don't have to wait other developers complete this refactoring task) but they won't be able to compile unless they update.
Step 3: when all has been done and everyone moved to new class then simply remove
Base.Manager.Logger
class from your code.Notes: that all process can be spanned across various releases: in 2.0 you deprecate old methods, in 2.1 you break compilation, in 3.0 you remove it from your code (this is especially useful if releases of your code and its users aren't in sync).
Just a word about name collisions: be aware that same class name (and methods) in two different namespace may lead to annoying name collisions. Imagine they have this code:
After your change (until
Base.Manager.Logger
isn't removed) they can't simply add anotherusing
:They need to full qualify which logger class they want to use:
Warning: be aware that if
Trace
isn't a new namespace then name collision may even break compilation immediately if they had bothusing
s in their code (makingObsoleteAttribute
useless).If it's an issue or not for you/your users...I can't say.