Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using DI with a shared library across applications

I'm facing a design challenge that I just can't seem to solve in a satisfactory way. I've got a class library assembly that contains all of my shared ORM objects (using EntitySpaces framework). These objects are used in 2 or more different applications which is why they are in their own assembly. This setup has worked fine for 4+ years for me.

I also have a couple of applications built on the Composite Application Block (CAB) from Microsoft's Patterns & Practices group (P&P). Yes, I know this is really old but I'm a part time developer, one-man-shop and can't afford to update to whatever the current framework is.

Here is where my problem comes in: I have been exercising my OO design skills and whenever doing a substantial refactoring I try to shift from a procedural approach to a more OO approach. Of course a major aspect of OO design is placing the operations close to the data they work with, this means that my ORM objects need to have functionality added to them where appropriate. This is proving a real head scratcher when I also consider that I'm using P&P's Object Builder DI container within CAB and that much of the functionality I would move into my ORM objects will need access to the services exposed by my applications.

In other words, let's say I have a shared business object called "Person" (original, I know) and I have two applications that do ENTIRELY different things with a person. Application A provides a set of services that the Person object would need to have DI'ed in order for it to take on some of the methods that are currently littered throughout my services layers. Application B also has a different set of services that IT needs to have DI'ed into the person object.

Considering how the P&P Object Builder resolves dependencies using attribute decoration and Type reflection I don't see how I can accomplish this. In a nutshell, I have a shared object that when used in various applications I would need to inject dependencies so that it can perform certain operations specific to that application.

The only approach I can come up with is to inherit a new Type in Application A & B from the Person object. I would then add my non-shared functionality and DI code into this application-specific specialized Person object. Now that I write that it seems so obvious, however it's still my only solution I can come up with and I wanted to ask here to see if anyone else had a different solution they would like to propose?

One problem I would have with my solution is that I can see myself getting caught up on naming my inherited type - I mean... it's a person, so what else would you call it? Anyways, hopefully you will have some ideas for me.

Also, I'm not hip on the current technologies that are out there and really, to be honest only barely grasp the ones I'm currently using. So if I've said something contradictory or confusing I hope you can understand enough from the rest of the post to get what I'm asking.

like image 638
scubasteve Avatar asked May 11 '11 02:05

scubasteve


1 Answers

It sounds like you're breaking the Single Responsibility Principle.

A Person object should just be holding the data for a person record. The services would then take in a Person object and manipulate it rather than having methods on the Person object that did that manipulation.

A classic example of this would be populating the Person object. Lets say app A grabs the data from a WebService, and app B grabs it from a database. In these cases I'd have some sort of Storage service that you call to get your Person object. Then implementation of that storage can be specific to each application, and be put into your IOC by the app, rather than trying to have a common interface in your shared assembly.

like image 194
Cameron MacFarland Avatar answered Nov 15 '22 06:11

Cameron MacFarland