Dependency Injection between Assemblies and Namespaces

I am working on a DI problem, which I think I understand the reason, but I need suggestions for work.

I built a separate assembly that speaks to Sql (call this assembly a) and another assembly that contains business logic (call this assembly b). I created an interface for the db class in assembly b. Since the interface is not part of the db assembly, I do not need references to the db project, and I can load the link to the db assembly or the stub if I want to run unit tests at runtime and I don't need to know anything else about the assembly.

I can write code in a business logic library that compiles that looks like this: (pretend a and b are namespaces in their respective assemblies)

a.IDatabaseClass db_class = (a.IDatabase)new b.Database(); 

When I try to run this, I get an invalid lit exception. I think that it compiles because the interface matches the class perfectly, but does not execute at runtime because the signature of the object does not see the IDatabase in the inheritance chain of the database class.

In C ++, you can get rid of casting, but you want to, but C # is a bit more strict regarding object pointers. Despite the fact that the class has all the correct function signatures, it explodes because the objects do not match.

Now I can put the interface of the db object in the assembly with the db object, but then the business logic needs a reference to the db assembly. In addition, it just complicates the work, because if I write a dub db object in unit test, I need a link to the db assembly only for the interface that I am going to use in my test stub. It does not seem to disengage the couplings, making it ...

I could put all the interfaces in the third assembly, which is the parent for the db assembly, business logic and unit tests. Here's how you can solve circular addiction problems. However, this associates the db assembly with the parent assembly and makes it much less modular for use with other projects.

I am open to suggestions on how I can configure each assembly so that they function independently and can be used for DI. I believe that I could store the test stub objects in the same assembly as the real code, but that seems weird.

Decision. One of the answers below makes a comment that what I shot is basically a duck for inputting interfaces. C # does not currently support duck printing, but I thought it was possible, since the implementation of the interface works similar to what you might call a partial class pointer (or, more precisely, a set of function pointers). My experiment showed me something else, and that is why.

so until Redmond adds “more mallard” to C #, it seems like we cannot fully achieve the final elegant level of decoupling of assemblies.

+5
source share
2 answers

Create a help library containing your common interfaces. Thus, you will have a common source with all the agnostic logic of implementation.

I have no experience to feel confident in making this a categorical expression, but I strongly suspect that communication is primarily a problem when you talk about individual types that reference specific interfaces and how they behave. Assemblies do not have the same specificity as the communication problem.

Change 1

Let me change and expand. One assembly must reference another, or both must reference a common assembly. C # does not have a duck interface if that is something.

Now I believe that it is best to isolate the business logic from external interfaces, so if you are going to do anything, you should isolate your business logic from the implementation of the database. Thus, the DB / Application assembly refers to business logic, but not vice versa.

Here is more information on dependency orientation .

+5
source

Let the client library ( b ) define the interface and reference this library from the server library ( a ).

From the Dependency Inversion Principle , it follows that "clients [...] own abstract interfaces" ( APPP , Chapter 11), so there is no reason to put an interface in a third library.

+3
source

Source: https://habr.com/ru/post/1237373/


All Articles