The modular architecture and UnitOfWork pattern in c#?

Hello. Specially checked in. Maybe here will have the answer to your question.

I write software using a modular architecture. That is, I have the Core and plug-ins using the objects, events, and more that provides core. The core is divided into layers. One of the layers of "Data Access Layer", abbreviated DAL, which allows to access the database. The main task of this layer is to abstract from the data source, because I need to support both mysql and postgresql. For data access I chose to use the UnitOfWork pattern, as I need to manage transaction. An example of this pattern can be found for example here https://metanit.com/sharp/mvc5/23.3.php
In this example, only 2 entities (tables). I have 15 tables so my UnitOfWork has 15 properties.
Everything is fine - I'm not writing repetitive code, you can easily change the database.

As I said early I have a modular architecture. When the module is passed the Instance of the UnitOfWork class and , accordingly, the module can use all fields (repository tables) and access their properties.

Here's a problem. That is, if the module needs to create their own table or to use additional functionality, then he can't do it, because in the instance of UnitOfWork no properties and certain methods. How to do, so the Kernel does not adjust to the modules, and the modules were adjusted to the core. And it is the modules used kernel for comfortable work with the base.

To injecting separate "Tables" in the methods - not a good idea - in the same module can be used up to 12 tables.

How to make sure that everything is extensible and independently? In the world of php e.g. Laravel, many simply create instances of the model inside the controller - but this is fu.

By the way, if what I write under desktop.
March 23rd 20 at 19:20
1 answer
March 23rd 20 at 19:22
When the module is passed the Instance of the UnitOfWork class and , accordingly, the module can use all fields (repository tables) and access their properties.

This is a clear disregard and violation of the Interface Segregation Principle. No need to do so.
Repository and UoW do not contradict each other. Give the service repository, but under the hood it could be any tools, including UoW.

That is, if the module needs to create their own table or to use additional functionality, then he can't do it, because in the instance of UnitOfWork no properties and certain methods.

The module changes the database schema? I think initially, to try to revise his logic.

How to do, so the Kernel does not adjust to the modules, and the modules were adjusted to the core. And it is the modules used kernel for comfortable work with the base.

At the core lies with the implementation of the work with the database, or only ads the necessary interfaces?
For implementations that have a separate Data Access Level.
Good on your layer with the business logic should declare the necessary interfaces to work with storage and access layer, these storage interfaces to implement. In the upper layer of the desired realization hits, respectively, via any mechanism, dependency inversion(DI)

A small note

One of the layers of "Data Access Layer", abbreviated DAL, which allows to access the database. The main task of this layer is to abstract from the data source, because I need to support mysql and postgresql

The task of this layer is to abstract the kernel from the vault and he can use any of the features of the desired database as he wants.

This is a clear disregard and violation of the Open-Close Principle. No need to do so.


Don't see a violation, because the kernel should not know which service to pass the module. The kernel should not try to adapt the modules.

Well. For example, I will make DAL from the kernel and make it a separate layer to which others can refer.

Give the service repository, but under the hood it could be any tools, including UoW.

I can do it and do, but the problem is that the repository may not be described the methods that I need.


The module changes the database schema? I think initially, to try to revise his logic.


Yes, the module should be able to change the structure as he desires. For example, the module Rating songs. Where he will store the rating data? Or initially to create the database in this table? And suddenly it may not be necessary as this module will not be needed.

The main thing for me that the module had its own DAL, which extends the basic complements it only needed the module properties. - Carlos commented on March 23rd 20 at 19:25
@Carlos,
Don't see a violation, because the kernel should not know which service to pass the module. The kernel should not try to adapt the modules.

Well. For example, I will make DAL from the kernel and make it a separate layer to which others can refer.

Violation of the OCP is to give each module a huge monster in the form of a UoW, 90% of the functionality which the module is not necessary, and indeed - where is the abstraction? Why do modules know about the Unit Of Work? Work with UoW is the DAL layer, as not any other.

Or initially to create the database in this table?

Of course initially, migration

And suddenly it may not be necessary as this module will not be needed.

I thought these things before developing the module, is the module there is a table. Removed the module, deleted the table(another migration)

The main thing for me that the module had its own DAL, which extends the basic complements it only needed the module properties.

Declare the necessary interface for store and injectate it in a module, at which stage the problem then?

As I wrote in the answer - work with the database is the outermost layer of the application, not the kernel level. - Eugenia commented on March 23rd 20 at 19:28

Find more questions by tags Designing softwareC#