简体   繁体   中英

Connection strings and multiple projects?

My project (using web api and EF6 and localdb) is structured the following way:

Projects:

LM.Api <-- is a web api project

LM.Console <-- is a console project

LM.DataAccess <-- is a class library that contains the models, the datacontext and the repository (LM.Api and LM.Console are referencing this project)

My question is:

How would I go about creating a common database for both LM.Api and LM.Console to use?

I've put a static string containing the connection string in LM.DataAccess. Both LM.Api and LM.Console get this and save it in their individual web.config/app.config files.

Is this a correct approach? When I access the repository from either project I get the exception:

The underlying provider failed on Open

Also, I would assume that the .mdf file should be placed in the LM.DataAccess project so I should enable migrations for that project, right?

You should definitely design your solution so that only the LM.DataAccess project would need a connection string and any specific knowledge of the database. This could be accomplished by abstracting out the data access to repository interfaces. These interfaces are part of the business logic of your application, hence they should be declared in LM.Api (or actually rather in a LM.BusinessLogic project since you may want to have access to the business logic from other projects as well).

But (and this is important) the repository implementations are declared in the LM.DataAccess project. So, in LM.BusinessLogic you have the interface:

interface ICustomerRepository
{
    void Insert(Customer customer);
    void Update(Customer customer);
    void Delete(int customerId);   
}

All other parts of your business logic only communicate with this interface when accessing the customer data.

In the LM.DataAccess you have the concrete implementation:

public class CustomerRepository : ICustomerRepository
{
    public void Insert(Customer customer)
    {
        using (var db = new DatabaseContext())
        {
            db.Customers.Add(customer);
            db.SaveChanges();
        }    
    }

    ... and so on
}

Then there's the tricky part of tying the interface and implementation together. You cannot have references in both directions, and since LM.DataAccess must have a reference to LM.BusinessLogic (it implements the repository interfaces declared there), the easiest way to get past this is to tie them together in a separate project that can be dependent on both. In your case this would be the LM.Api project, I think. And maybe the LM.Console project as well?

I always use an Inversion of control-container to provide the needed interface through constructor injection, since it makes it things so much easier. ( Autofac is my favorite, but there are several others)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM