Using DI with a shared library through applications

I ran into a design problem that I just cannot solve in a satisfactory way. I have a class library assembly that contains all of my common ORM objects (using the EntitySpaces framework). These objects are used in two or more different applications, so they are in their own assembly. This setting worked great for me for over 4 years.

I also have several applications built on the Composite Application Block (CAB) from the Microsoft Patterns and Practices (P & P) group. Yes, I know that itโ€™s really old, but Iโ€™m a part-time developer, one person-shop, and I canโ€™t afford to update all the current frameworks.

This is where my problem lies: I train my OO design skills and whenever I do substantial refactoring, I try to move from a procedural approach to a higher OO approach. Of course, the main aspect of OO design is that operations come close to the data they work with, which means that my ORM objects must have functionality added to them where necessary. This proves the real head scraper, when I also believe that I use the P & P Object Builder DI container inside the CAB, and most of the functions that I will move to the ORM objects will need access to the services, / p>

In other words, let's say I have a common business object called "Face" (the original, I know), and I have two applications that USE different things with a person. Appendix A provides a set of services for which a Person must have a DI'ed so that it can use some of the methods that are currently clogged at all service levels. Appendix B also has a different set of services that IT must have DI'ed in the person object.

Given how the P&P Object Builder resolves dependencies using attribute decoration and type reflection, I donโ€™t see how I can do this. In general, I have a common object, which when used in various applications, I will need to enter dependencies so that it can perform certain operations specific to this application.

The only approach I can come up with is to inherit a new application type A and B from the Person object. Then I will add my non-general functions and DI code to this specialized specialized Person object. Now when I write that it seems so obvious, however it is still my only solution that I can come up with and I wanted to ask here, does anyone have any other solution that they would like to offer?

One of the problems that I would encounter with my solution is that I can see how I am in naming my inherited type - I mean ... this is a person, so what else would you name? In any case, I hope you will have some ideas for me.

In addition, Iโ€™m not sure about the current technologies that are and really, frankly, itโ€™s hardly possible to understand the ones that I am currently using. Therefore, if I said something contradictory or confusing, I hope you can understand enough from the rest of the message to get what I ask.

+8
c # oop dependency-injection orm
source share
3 answers

You seem to be violating the principle of shared responsibility .

An object

A Person should simply store data for a personโ€™s record. Then the services will use the Person object and manipulate it, and not have methods for the Person object that performed this manipulation.

A classic example of this would be populating a Person object. Suppose application A grabs data from a WebService, and application B grabs it from a database. In these cases, I will have some kind of Storage service that you call to get your Person object. Then the implementation of this repository may be specific to each application and be placed in your IOC by the application, rather than trying to have a common interface in your common assembly.

+3
source share

I agree with Cameron MacFarland on this: you are violating SRP.

Of course, the main aspect of OO design puts operations close to the ones they work with, which means that my ORM objects must have functionality added to them, where appropriate

Data placement and functionality from A AND functions from B is too much responsibility. Listening to SRP almost always leads to the separation of data and functionality in separate classes (data structures and objects). So using Cameron MacFarlands sugestion is probably the best way to go.

+1
source share

I could think of several approaches to solve this problem.

  • Separate the behavior specific to each person / application separately. Dependency injection using the installer in the application itself.

Apporach1


 public interface IPerson { IPersonApp1 Person1 {get; set;} IPersonApp2 person2 {get; set;} } class Person : IPerson { IPerson1 Person1 {get; set;} IPerson2 Person2 {get; set;} } 

  public interface IPerson1 { // App1 specific behavior here void App1SpecificMethod1(); } class Person1: IPerson1 { void App1SpecificMethod1() { // implementation } } class App1 { IPerson objPerson; // Dependency injection using framework App1(IPerson objPerson) { this.objPerson = objPerson; // Dependency injection using setter this.objPerson.Person1 = new Person1(); } } 

  • Separate the behavior specific to each person / application separately. Inject dependencies in the Person constructor.

Apporach2


 class Person : IPerson { IPerson1 Person1 {get; private set;} IPerson2 Person2 {get; private set;} // DI through constructor. If the type IPerson1 or IPerson2 are not registered, it will be set to null. Person(IPerson1 objPerson1, IPerson2 objPerson2) { this.Person1 = objPerson1; this.Person2 = objPerson2; } } 

The user interface project must have a link to IPerson1 and IPerson2, or you can declare IPerson1 and IPerson2 in the Person interface project itself.

0
source share

All Articles