alastairs
alastairs

Reputation: 6805

How to inject a dependency when deciding which dependency to use requires the use of the dependency

I have a classic bootstrapping problem. I am trying to inject the TFS client libraries for version control into my application, but I need to load different versions of the client library in different situations: the TFS 2013 client libraries cannot connect to TFS 2005 or TFS 2008 servers, so I need to load an earlier version of the client libraries when connecting to these older versions of TFS. I have found that I can reliably determine the version of TFS that I am connecting to by requesting the BuildServerVersion property from the IBuildServer service.

Normally I would solve this problem using an Abstract Factory pattern and use an IoC container to load the appropriate factory implementation; however, normally the decision would be entirely the responsibility of the application. In my situation, the decision is based on the response from the TFS server, and, crucially, I have to load a version of the TFS client library to request that information from the TFS server in the first place.

What approaches can I consider to address this problem?

Upvotes: 1

Views: 99

Answers (2)

Mark Seemann
Mark Seemann

Reputation: 233487

Since it sounds like it's possible to have multiple versions of the client libraries loaded at the same time, the easiest solution is probably to take a hint from the Interface Segregation Principle. Define a Role Interface with the sole purpose of figuring out the BuildServerVersion.

It might be something like

public interface IBuildServerVersionQuery
{
    Version GetBuildServerVersion();
}

You can then write an Adapter around one of the client libraries and use it to get the BuildServerVersion.

Then, when you have the BuildServerVersion, you can use it to implement an Abstract Factory that returns the real client library.

You can also use one of these selection mechanisms, such as Metadata, Role Interfaces, or (my preferred) Partial Type Name, to select the appropriate client library.

Unless the GetBuildServerVersion() method returns the version corresponding to the client library that implements IBuildServerVersionQuery interface itself, this means that you'll have a (now) redundant client library loaded into the AppDomain, but is that really a problem?

Upvotes: 3

JohnStov
JohnStov

Reputation: 11

Can you load a version of the TFS libs in an AppDomain? Then you can make the call, unload the AppDomiain, which will unload the libs, and reload the correct version.

Upvotes: 1

Related Questions