Add Version to Existing DLLs Maintaining Backwards Compatability - c#

I have a product that I need to add dynamic versioning to our core level components, so that the main application can check for version inconsistencies before allowing certain things to execute. Some background:
All components implement an interface that I have defined
There is no base class that the components derive from, they all implement the root interface directly
I can add a new int Version property and/or methods to the interface
I need to maintain backwards compatibility with DLLs that already "in the wild" and deployed. If a DLL doesn't implement the version checking APIs (because its old), assume it will work properly
So I was thinking of adding a bool CheckVersion() method to the interface, and then checking if that method exists before invoking it. If the method doesn't exist, then just don't invoke it.
I don't like the idea of checking if the method exists because it is expensive and clutters up the code (e.g., "Why is this weird invocation check necessary?")
Anyone have any better ideas?

Related

Difference between the different Solution interfaces

When writing an VSIX and you want to access information about the given solution you can simply do DTE2.Solution which will return Solution, so far so good. When looking at the MSDN I can see that there exist multiple solution interfaces: Solution, Solution2, Solution3 and Solution4.
I noticed that the VSIX SDK rather often does this, for whatever reason, in order to offer different functionality. In this case I can't really spot any big difference and I am not really sure when I should use which. Should you always go for Solution4 since it implements all the predecessors?
... for whatever reason, in order to offer different functionality
These are COM interfaces so they're subject to COM rules. Once an interface is published, it is immutable, so adding functionality is done by defining a new interface that inherits from the old.
Numeric suffixes were the convention Microsoft used for versioning COM interfaces. .NET guidelines for interfaces advise against this but, for consistency, the pattern continues in Visual Studio.
Querying a COM interface involves reference counting. That means a call to QueryInterface to get a pointer to the desired interface, and ultimately a call to Release to tell the object you no longer need the reference. The object itself is responsible for its lifetime. The constructor (called by the object's class factory) starts its reference count at 1, and Release deallocates the memory (deletes itself) when the reference count hits 0.
Note that "reference" in this context is not the same as a .NET reference. It's a counted copy of a pointer to one of the object's interfaces.
In the early days, it took a bit of work to make sure you handled the reference correctly. If you can query a newer interface with the combined functionality, that was less work than querying both interfaces separately and ensuring that both were released properly. Inheriting an interface made things easier by reducing reference management.
Now, we have smart pointers, like CComPtr/_com_ptr_t, that can handle those details for you. In the managed world, Runtime-Callable Wrappers (RCW) count that among their responsibilities.
In .NET, it's just as easy to create a new interface as it is to inherit an existing one, and just as easy to use the interface in either case. It's just a matter of a reference cast and sometimes that happens implicitly.
C# 8 adds default implementations but that's a .NET-specific feature. Remember, Visual Studio is still using COM interfaces at its core. Default implementations violate the COM rules.
Should you always go for Solution4 since it implements all the predecessors?
That depends on what you're targeting. As a general rule, use the minimal interface version that has the members you need. If you need members from Solution and Solution3, use Solution3, but not Solution4.
On the other hand, if you know you're targeting at least a version of Visual Studio that implements Solution4, there's no reason you couldn't use Solution4. Once you're certain that you're not accidentally preventing your extension from running in the Visual Studio versions you want to target, it falls to your preference.

Dependency Inversion: How to best manage versioning of your Abstractions

How to version abstractions in .Net when applying Dependency Inversion in a high code-reuse environment
I am interested in shifting toward using Dependency Inversion in .Net, but have come across something that puzzles me.
I don’t believe it is tied to a particular method or provider of DIP, but more a fundamental issue that perhaps others have solved. The issue I'm solving for is best laid out step-by-step as scenario below.
Assumption / Restriction
A considerable assumption or restriction to put out there up front, is that my development team has stuck with a rule of keeping our deployed assemblies to one and only one Assembly Version, specifically version “1.0.0.0”.
Thus far, we have not supported having more than this one Assembly Version of any given assembly we’ve developed deployed on a server for the sake of simplicity. This may be limiting, and there may be many good reasons to move away from this, but never the less, it is currently a rule we work with. So with this practice in mind, continue below.
Scenario
You have an IDoStuff interface contained in an abstraction assembly
Stuff.Abstractions.dll with 2 methods.
You compile component A.dll
with a class explicitly implementing IDoStuff with 2 methods.
You move A.dll to production use, Assembly Version 1.0.0.0, Assembly File
version 1.0.0.0.
You move Interface.dll to prod, Assembly Version
1.0.0.0, Assembly File version 1.0.0.0.
Everything works fine. Time passes by.
You add another method (“DoMoreStuff” for example) to the IDoStuff interface so that a different Component B can call it.
(Keeping Interface Segregation OO principle in mind, let’s say the DoMoreStuff method makes sense to be in this relatively small IDoStuff interface.)
You now have IDoStuff with 3 methods in Stuff.Abstractions.dll, and you’ve built Component B to use the new 3rd method.
You move Stuff.Abstractions.dll to production use (upgrade it), Assembly Version 1.0.0.0, Assembly File Version 1.0.0.1.
(note that the file version is incremented, but the assembly version and therefore the strong name stays the same)
You move B.dll to production use, Assembly Version 1.0.0.0, Assembly File version 1.0.0.17.
You don’t do a thing to A.dll. You figure there are no changes needed at this time.
Now you call code that attempts to execute A.dll on the same production server where it had been working before. At runtime the Dependency Inversion framework resolves the IDoStuff interface to a class inside A.dll and tries to create it.
Problem is that class in A.dll implemented the now extinct 2-method IDoStuff interface. As one might expect, you will get an exception like this one:
Method ‘DoMoreStuff’ in type ‘the IDoStuff Class inside A.dll’ from assembly ‘strong name of assembly A.dll’ does not have an implementation.
I am presented with two ways that I can think of to deal with this scenario when I’d have to add a method to an existing interface:
1) Update every functionality-providing assembly that uses Stuff.Abstractions.dll to have an implementation of the new ‘DoMoreStuff’ method.
This seems like doing things the hard way, but in a brute-force way would painfully work.
2) Bend the Assumption / Restriction stated above and start allowing more than one Assembly Version to exist (at least for abstraction definition assemblies).
This would be a bit different, and make for a few more assemblies on our servers, but it should allow for the following end state:
A.dll depends on stuff.abstractions.dll, Assembly Version 1.0.0.0, Assembly File Version 1.0.0.22 (AFV doesn’t matter other than identifying the build)
B.dll depends on stuff.abstractions.dll, Assembly Version 1.0.0.1, Assembly File Version 1.0.0.23 (AFV doesn’t matter other than identifying the build)
Both happily able to execute on the same server.
If both versions of stuff.abstractions.dll are installed on the server, then everything should get along fine. A.dll should not need to be altered either. Whenever it needs mods next, you’d have the option to implement a stub and upgrade the interface, or do nothing. Perhaps it would be better to keep it down to the 2 methods it had access to in the first place if it only ever needed them.
As a side benefit, we’d know that anything referencing stuff.abstractions.dll, version 1.0.0.0 only has access to the 2 interface methods, whereas users of 1.0.0.1 have access to 3 methods.
Is there a better way or an accepted deployment pattern for versioning abstractions?
Are there better ways to deal with versioning abstractions if you’re trying to implement a Dependency Inversion scheme in .Net?
Where you have one monolithic application, it seems simple since it’s all contained – just update the interface users and implementers.
The particular scenario I’m trying to solve for is a high code-reuse environment where you have lots of components that depend on lots of components. Dependency Inversion will really help break things up and make Unit Testing feel a lot less like System Testing (due to layers of tight coupling).
Part of the problem may be that you're depending directly on interfaces which were designed with a broader purpose in mind. You can mitigate the problem by having your classes depend on abstractions which were created for them.
If you define interfaces as needed to represent the dependencies of your classes rather than depending on external interfaces, you'll never have to worry about implementing interface members that you don't need.
Suppose I'm writing a class that involves an order shipment, and I realize that I'm going to need to validate the address. I might have a library or a service that performs such validations. But I wouldn't necessarily want to just inject that interface right into my class, because now my class has an outward-facing dependency. If that interface grows, I'm potentially violating the Interface Segregation Principle by depending on an interface I don't use.
Instead, I might stop and write an interface:
public interface IAddressValidator
{
ValidationResult ValidateAddress(Address address);
}
I inject that interface into my class and keep writing my class, deferring writing an implementation until later.
Then it comes time to implement that class, and that's when I can bring in my other service which was designed with a broader intent than just to service this one class, and adapt it to my interface.
public class MyOtherServiceAddressValidator : IAddressValidator
{
private readonly IOtherServiceInterface _otherService;
public MyOtherServiceAddressValidator(IOtherServiceInterface otherService)
{
_otherService = otherService;
}
public ValidationResult ValidateAddress(Address address)
{
// adapt my address to whatever input the other service
// requires, and adapt the response to whatever I want
// to return.
}
}
IAddressValidator exists because I defined it to do what I need for my class, so I never have to worry about having to implement interface members that I don't need. There won't ever be any.
There's always the option to version the interfaces; e.g., if there is
public interface IDoStuff
{
void GoFirst();
void GoSecond();
}
There could then be
public interface IDoStuffV2 : IDoStuff
{
void GoThird();
}
Then ComponentA can reference IDoStuff and ComponentB can be written against IDoStuffV2. Some people frown on interface inheritance, but I don't see any other way to easily version interfaces.

I want to modify an opensource wpf library, but update it as the donor library improves: how?

I'm intending to extend & alter an opensource library (LIB_A), which is itself composed of other libraries which have been modified for it's release.
My modifications are probably to be made to all of the libraries.
What is the best way to make subsequent importing of LIB_A into my library as painless as possible when new features are added/bugs are squished, without creating integration issues?
I was thinking of having my library sublass the classes I want to change, and override methods I want to change, but can't figure out if this is possible. The reasoning here is that I might only modify two methods in each class, so that when LIB_A bugs are fixed, if they're not in my modified methods - there is no collision, and I take advantage of the updates for free. If they are in the same method, there's no way around that, which I accept.
If I just copy the whole LIB_A, then I'll have to laboriously go through every file with a diff to see what has been changed, and then incorporate the updates. There must be an established way of doing this?
Is a source repository (local or otherwise) with it's associated check-in and diff behaviour the accepted method?
Thanks
EDIT: This SO question is asking exactly the same thing..
Well, you said it. If you can do it by subclassing, then by all means this is the simplest method.
The problem is that you not always can do it just via subclassing -- e.g. when you need to change a sealed or private method, change other non-virtual methods or properties etc. In this case, there is nothing you can do except to either (1) copy the code and create your own version, (2) modify the code such that those methods/properties are virtual and public -- but make sure it doesn't break anything elsewhere.
Even if you can subclass it, and the new version of the library does not touch the few methods that you overrode, you still have to test your changes fully agian, because your new code may depend on certain implementation details that the new version changed. Of course, the vendor of the library will have modified those few methods for the new version, but your version won't change. So the best way is to do a diff of the vendor's new version of your overridden methods with the old version to detect whether you need to change something in your own version as well.

Any way to avoid creating a huge C# COM interface wrapper when only a few methods needed?

Greetings all,
I’m working on a C# program that requires being able to get the index of the hot item in Windows 7 Explorer’s new ItemsView control. Fortunately, Microsoft has provided a way to do this through UI Automation, by querying custom properties of the control.
Unfortunately, the System.Windows.Automation namespace inexplicably does not seem to provide a way to query custom properties! This leaves me with the undesirable position of having to completely ditch the C# Automation namespace and use only the unmanaged COM version. One way to do it would be to put all the Automation code in a separate C++/CLI module and call it from my C# application. However, I would like to avoid this option if possible, as it adds more files to my project, and I’d have to worry about 32/64-bit problems and such.
The other option is to make use of the ComImport attribute to declare the relevant interfaces and do everything through COM-interop. This is what I would like to do. However, the relevant interfaces, such as IUIAutomation and IUIAutomationElement, are FREAKING HUGE. They have hundreds of methods in total, and reference tons and tons of interfaces (which I assume I would have to also declare), almost all of which I will never ever use. I don’t think the UI Automation interfaces are declared in any Type Library either, so I can’t use TLBIMP.
Is there any way I can avoid having to manually translate a bajillion method signatures into C# and instead only declare the ten or so methods I actually need? I see that C# 4.0 added a new “dynamic” type that is supposed to ease COM interop; is that at all relevant to my problem?
Thanks
The most important thing (from the perspective of calling a COM method from C#) is that the methods appear in the interface in the right order. If you're not using a method, you can just declare it as void and nothing bad will happen (unless you actually call it!). This saves you from having to work out the correct signatures and define all the other types, etc. For example,
[ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUIAutomation
{
void CompareElements();
void CompareRuntimeIds();
void GetRootElement();
// 50 or so other methods...
// ... define only the signatures for the ones you actually need
}
The methods should be defined in exactly the same order they appear in UIAutomationClient.h (in the Windows SDK).

.NET 3.5: Dynamically adding classes without recompiling

I'd like to build an infrastructure that will monitor a server and check ping, response time, and more.
The catch is that future checks (for example: does a certain file exist) will be added without recompiling the infrastructure.
How do I build it in such a way that will enable me to attach inherited classes with different functionality, and execute them without recompiling?
Thanks!
In addition to creating an interface and defining a single entry point for your new library, you could create an attribute which identifies the classes that you need to load or the methods that you need to call. You then use reflection to look at all the DLLs in a certain path, and instantiate / run whatever contains your attribute.
I've built a similar application that had to perform a number of health checks on a system, and needed to be extensible. The application started, looked through all the DLLs in a specified path and for each class with the 'TestAttribute' decoration it would create an instance and run the 'Execute' method.
The use of an attribute means that you don't need to specify which DLLs to process (doesn't need to be in config / database) because it's safe to process every DLL, and only those decorated with the attribute will do anything.
Implement an interface, and the provider pattern, then you can plug anything in that you like. MSBuild is a great example of this, with a simple interface you can add any type of task you like to your build process - follow the same sort of pattern.
Sounds like you could use some kind of 'plugin' mechanism. Define a basic interface and you can compile every "check/action" into a separate assembly. Load all your assemblies dynamically from file and call execute the check/action via the defined interface.
The interface could be just as simple as this, for starters:
public interface IMonitorAction
{
bool Exectute();
}
This infrastructure allows you to add more checks by just creating another assembly file implementing the interface next to the existing ones.
Of the top of my head.
I presume you can re-start you application.
Have a file that lists all the DLL's to load that implement your required functionality. Each DLL should have the same name entry point. Load each DLL, call the method, unload DLL. loop.
Caveat: I've never done anything like this, so I may be talking hot air.
Adding to #slugsters answer, instead of building your own extensibility infrastructure, take a look at extensibility libraries like MEF.

Categories