We developed a generic .NET library for our line-of business applications. This is what our namespace/class structure looked like 5 years ago:
...
AcmeCorp.Tools.ExcelWriter
AcmeCorp.Tools.Code128Barcode
...
5 years later, the number of classes in the generic Tools
namespace has grown (e.g. there's now a CSVWriter
in addition to an ExcelWriter
and a QRBarcode
in addition to a Code128Barcode
). Thus, I'd like to refactor the namespaces to look like this:
...
AcmeCorp.Export.ExcelWriter
AcmeCorp.Export.CSVWriter
AcmeCorp.Export.SomeUtilityClassUsedByAllExportClasses
AcmeCorp.Barcode.Code128Barcode
AcmeCorp.Barcode.QRBarcode
...
I know how to refactor namespaces in C# - that's not the question. The question is: How do I keep my library backwards-compatible?
Ideally, I'd like to do something like this:
namespace AcmeCorp.Barcode
{
[AlsoAvailableViaDeprecatedLegacyNamespace("AcmeCorp.Tools")]
public class Code128Barcode
{
...
}
}
which would automatically create a proxy class AcmeCorp.Tools.Code128Barcode
which (a) redirects all calls to the new class and (b) annotates the proxy class with the [Obsolete("Use AcmeCorp.Barcode.Code128Barcode instead.")]
attribute. Alas, no such AlsoAvailableViaDeprecatedLegacyNamespace
attribute exists. (Or does it?)
The only other solution I could think of would be to write such a proxy class myself, which would be a lot of useless boilerplate code.
Is there any other solution that I have missed? To reiterate: My goal is to
- move classes into a more suitable namespaces, but
- keep the library backwards-compatible (no source-level or binary-level breaks),
- avoid code duplication and boilerplate code (as far as possible), and
- (bonus:) mark all uses of the "old" namespace as obsolete.