Code Monkey home page Code Monkey logo

Comments (5)

christianpeters78 avatar christianpeters78 commented on July 17, 2024

Hi,

how do you plan to use an Extension-method with an IDbContextCollection_interface which by itself references System.Data.Entity?

from dbcontextscope.

patroza avatar patroza commented on July 17, 2024

Hi,

My main problem was not having a reference to EntityFramework, but having a reference from my Application layer into my Infrastructure layer.

So my application layer has interfaces for Infrastructure. But Infrastructure layer implements these interfaces.
Application layer does not have access to the implementations in Infrastructure, instead the Presentation/DI layer wires them up.
so my workaround makes it possible to deal with the interfaces instead of the implementation.

In essence it's the Onion architecture: http://chicagoalt.net/event/july-2011-meeting-onion-architecture-with-asp-net-mvc

So in short I do not mind having a reference to a 3rd party library to make an extension method work.
as in general we need to do that anyway to access all the IQueryable magic residing in there. (while its not 'pure', it is acceptable to me)
However I do have problems with changing my app's layered architecture.

from dbcontextscope.

christianpeters78 avatar christianpeters78 commented on July 17, 2024

Hi,

understood. So this is not quiet what I thougt.
My "problem" is, that the business-layer depends on the EntityFramework and I don't see how to resolve this issue without rewiting the DbContextCollection.

But that's not for here. ;o)

from dbcontextscope.

patroza avatar patroza commented on July 17, 2024

I see, well personally I do not believe the business layer should access EF, either directly or indirectly through either concrete nor abstract repositories.
But that is another type of discussion :)

Also how far did you abstract away EF in the business layer, because if you access the Db from business layer, wouldn't you always have to have access due to the EF extensions, IQueryable provider etc?

from dbcontextscope.

maldworth avatar maldworth commented on July 17, 2024

Hi Sickboy,

The situation you describe in your first and third posts here are similar to mine but I'm a bit curious as to your implementation.

Basically I'm wondering what your ISqlContext (and/or IDbContext) look like.

Here's what I was thinking. I simplified and left out some things, but enough there for you to understand what I'm trying to get at. Questions below the example.

// ######## 
// Domain
// ########

public interface IDbContext
{
}

public interface ISqlContext : IDbContext
{
    public DbSet<Employee>  Employees   { get; }
    public DbSet<Manager>   Managers    { get; }
    public DbSet<Staff>     Staff       { get; }
}

public interface IMySqlContext : IDbContext
{
    // another db context if we want
}

// ########
// Application Layer
// ########

SomeQueryHandler : IQueryHandler<TInput, TOut>
{
    private IDbContextScopeFactory  _dbContextScopeFactory  { get; set; }   // DI through constructor or property.
    // Your setup code
    // ...

    public TOut Execute(TInput)
    {
        using(var dbContextScope = _dbContextScopeFactory.CreateReadOnly())
        {
            ISqlContext dbCtx = dbContextScope.DbContexts.GetByInterface<ISqlContext>();

            // Do our DB query, with full access to the DbSet magic that is offered through IQueryable
            // I can't think of another way to do it, because IDbScopeCollection must return a type that inherits DbContext
            // and your extension method must return an IDbContext
        }
    }
}

SomeCommandHandler : ICommandHandler<TCommand>
{
    private IDbContextScopeFactory  _dbContextScopeFactory  { get; set; }   // DI through constructor or property.
    // Your setup code
    // ...

    public void Execute(TCommand)
    {
        using(var dbContextScope = _dbContextScopeFactory.Create())
        {
            ISqlContext dbCtx = dbContextScope.DbContexts.GetByInterface<ISqlContext>();

            // Again do Db Calls on the DbSets, but how would I call any methods that are part of the DbContext?

            dbContextScope.SaveChanges();
        }
    }
}

// ########
// Infrastructure Layer
// ########

public MyContext : DbContext, ISqlContext
{
    public MyContext : base("myconnectionstring")
    {
    }

    public DbSet<Employee>  Employees   { get; set; }
    public DbSet<Manager>   Managers    { get; set; }
    public DbSet<Staff>     Staff       { get; set; }
}

// ########
// Composition Root, assign our static funcs
// ########

DbContextScopeExtensions.GetDbContextFromCollection = (collection,type) =>
{
    if(type == typeof(ISqlContext)) return collection.Get<MyContext>();

    //return a default context? not quite sure what to do here.
}

So I don't really like having to define the DbSet in the ISqlContext. Also, because the extension method returns the interface, which only knows about the DbSets. Then I don't have access to any methods from the DbContext.

So I thought maybe the purpose of IDbContext was to have a property to the context.

// ########
// Domain
// ########

public interface IDbContext
{
    public DbContext DbCtx  { get; }
}

public interface ISqlContext : IDbContext
{
}

// ########
// Application
// ########

// Making appropriate changes, I also access the DbSets using the DbContext.Set<TEntity>()


// ########
// Then in your Infrastructure
// ########

public MyContext : DbContext, IDbContext
{
    public MyContext : base("myconnectionstring")
    {
    }

    public DbContext DbCtx  {
        get {
            return this;
        }
    }

    // Assign DbSets here instead of in the ISqlContext
    public DbSet<Employee>  Employees   { get; set; }
    public DbSet<Manager>   Managers    { get; set; }
    public DbSet<Staff>     Staff       { get; set; }
}

What do you think about this better, as the application layer cannot see the DbContext implementation, so we are okay there, and yet we have access to the DbContext Methods, and can still call the DbSets as well.

from dbcontextscope.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.