2

I'm interacting with a large code base (in a single assembly) written by another department (let's call it BusinessAssembly). Precious few of the objects we need to use in that assembly use interfaces. As a result, LOTS of our projects need to reference that assembly because there is no abstraction available and tests are difficult to write.

To further complicate matters, it now looks as though we may need to be able to support multiple versions of the BusinessAssembly and switch between them either at build-time or run-time. E.g. BusinessAssembly2 will add new objects which we'll need to use, but BusinessAssembly1 won't contain those objects.

My only promising solution so far is to create two separate projects in our solution, one that references BusinessAssembly1 (BusinessProxy1) and another that references BusinessAssembly2 (BusinessProxy2). These projects would contain proxies and decorators around the individual BusinessAssembly objects (e.g. BusinessUserProxy), and those proxies and decorators would implement interfaces (IBusinessUserProxy).

If I've thought this through correctly, an abstract factory could then provide the requested proxy/decorator object from the correct proxy/decorator project at run-time and our other projects could abandon their references to the giant assembly and simply use the interfaces the various proxies/decorators implement.

I'm not trying to alter the behaviour of the objects, but another consideration here is that we would like to gain the ability to provide test doubles for the various BusinessAssembly objects, which this approach should provide.

However, this approach does come with a considerable amount of development overhead: when BusinessAssembly3 creates ten new objects, we'll need to write proxies and interfaces for each of those.

My question(s): Is it an acceptable use of proxies to merely provide an interface for an object that otherwise has no interface? Would a different approach avoid the development overhead?

Also, I'm terribly ill right now so let me know if I'm not being clear or if I didn't actually even type any real words here.

4

If BusinessAssembly2 contains all of BusinessAssembly1's public members, then you could write one or more Interfaces for that subset of members, which could be used as a constructor parameter in one or more Facade classes, thereby providing Dependency Injection. That would allow you to switch between either version of the underlying business assemblies at either design time or runtime, as needed.

It would also allow you to build test classes that implement those interfaces, and pass those into your Facade for testing purposes.

You'd still need to create or extend your Interfaces and Facade classes when BusinessAssembly3 came out. I don't see any way around that, unless using the new classes directly is acceptable.

If those business assemblies are large, you could save yourself a lot of tedious manual work by building a little code generator that inspected them via Reflection and output Interfaces and Facade classes.

|improve this answer|||||
  • Can't modify BusinessAssembly at present, sadly; so objects in those assemblies cannot implement interfaces. – Pete Scott Oct 12 '14 at 1:46
  • 2
    BusinessAssembly wouldn't implement those interfaces; your pass-through Facade classes would. – Troy Gizzi Oct 12 '14 at 1:47
  • Ah. That's a good idea, saves a good deal of object creation. I'll toy with that tomorrow before definitively accepting the answer. Thanks! – Pete Scott Oct 12 '14 at 1:50
  • This works well. Still unpleasant (due to circumstance), but much simpler to work with than my plan. Many thanks! – Pete Scott Oct 12 '14 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.