Edgar Froes
Edgar Froes

Reputation: 778

How to remove EntityFramework.SqlServer Reference from WebApplication project in a DDD Solution

I have a highly standardized project in DDD (Domain-Driven Design), so it means that each layer has it's responsibilities and no layer knows other than itself and the Domain Layer.

Here's the structure of my project:

My DDD Project Structure

My Infra.Data layer is responsible for connecting with the Database, and i'm persisting using EntityFramework.

My problem is: in order to make it work with SQLServer Databases, i need to add a reference to EntityFramework.SqlServer in my WebApplication layer, which breaks my separation of concerns concept, as you can see below.

EntityFramework.SqlServer reference in the WebApplication layer (wrong!)

Even having the same reference in my Infra.Data layer, which is where it only should be, as you can see below.

Right reference of EntityFramework.SqlServer on the right project

If i remove the EntityFramework.SqlServer reference from the WebApplication layer, it stops working, and throws exception every time i try to persist data, as you can see below.

Exception generated when trying to persist Data without EntityFramework.SqlServer reference in the WebApplication

I need to know how to remove this reference to keep separation of concerns, because the way it is now, i'll have to change my WebApplication if i want to change my persistence. My Web layer is prohibited to even have anything with the word "EntityFramework" in it. I want FULL separation of concerns to change any layer without affecting no other.

If i register my <entityFramework> provider in my Web.config file, it will only works if i have the EntityFramework.SqlServer in the project, but without the EntityFramework.SqlServer reference on the WebApplication, it miss namespaces and complain about it.

Note: My project also connects to MySql Databases successfully, and i don't need no references to MySql.Data or any other MySql library in my WebApplication layer, as expected.

Please help me, my DDD/Separation of Concerns OCD is cracking on it, thanks.

Upvotes: 2

Views: 529

Answers (2)

MHOOS
MHOOS

Reputation: 5306

You would not be able to get rid of Entity-framework configuration and the required DLL in your Web-application :

  • Lets say your infrastructure layer and domain layer need to depend on Entity-framework. This means these two libraries need to have physical access to Entity Framework DLLs(Have Entity-framework package installed) and configured.
  • When you run your web application which has dependency on infrastructure and domain libraries, all Dlls used by underlying libraries (infrastructure and domain) need to be present physically and configured otherwise you will have run time issue(program might be compile-able but you will get run-time errors).

Morale of the story : If application x [Irrespective of the layer it belongs to] has dependency to library y,z and library y,z rely on some dll and require configuration, for application x to work at run-time you need to have all dlls needed by y,z available and provide their configuration (web.config) in your instance.

You can obviously provide some workarounds such as copying the files directly and providing separate config files for each layer but I strongly advise against it because it would get extremely messy and very hard to maintain in the long run.

Upvotes: 0

Florin D. Preda
Florin D. Preda

Reputation: 1378

You can!

Just create this class in your Infra.Data project:

internal static class ForceEFToCopyDllToOutput
{
    private static SqlProviderServices instance = SqlProviderServices.Instance;
}

When you do this you let the compiler know that the specific resource is used and should be available in the bin folder.

Some consider this a hack but it's useful if you want to keep your layers free from infrastructure concerns.

You can read more about this here: DLL reference not copying into project bin

EDIT:

All you'll need now is to copy the connection string from your Infra.Data app.config to your WebApplication web.config

<connectionStrings>
    <add name="DatabaseConnectionString" providerName="System.Data.SqlClient" connectionString="..." />     
</connectionStrings>

Upvotes: 2

Related Questions