Question

Using the EF5 implementation of SharpRepository, how can I share the DBContext amongst different instatiations of the IRepository when using the RepositoryFactory ?

Code snippet:

using SharpRepository.Repository;

public class PersonManager()
{

    private IRepository<Domain.PersonIdentifier, int> personIdentifierRepository;
    private IRepository<Domain.NextNumber, string> nextNumberRepository;

    public PersonManager()
    {

        //HOW TO SHARE A SINGLE DBCONTEXT INSTANCE BETWEEN THESE TWO INSTANTIATIONS ??
        this.personIdentifierRepository = RepositoryFactory.GetInstance<Domain.PersonIdentifier, int>();
        this.nextNumberRepository = RepositoryFactory.GetInstance<Domain.NextNumber, string>();

    }

}

Web.config file:

<sharpRepository>
    <repositories default="EF5Repo">
      <repository name="EF5Repo" connectionString="MyContainer" factory="SharpRepository.Ef5Repository.Ef5ConfigRepositoryFactory, SharpRepository.Ef5Repository" />
    </repositories>
    <cachingProviders default="inmemory">
      <cachingProvider name="inmemory" factory="SharpRepository.Repository.Caching.InMemoryConfigCachingProviderFactory, SharpRepository.Repository" />
    </cachingProviders>
    <cachingStrategies default="noCaching">
      <cachingStrategy name="timeout" timeout="30" factory="SharpRepository.Repository.Caching.TimeoutConfigCachingStrategyFactory, SharpRepository.Repository" />
      <cachingStrategy name="standardCachingStrategy" generational="true" writeThrough="true" factory="SharpRepository.Repository.Caching.StandardConfigCachingStrategyFactory, SharpRepository.Repository" />
      <cachingStrategy name="noCaching" factory="SharpRepository.Repository.Caching.NoCachingConfigCachingStrategyFactory, SharpRepository.Repository" />
    </cachingStrategies>
  </sharpRepository>

Thanks

Was it helpful?

Solution

The RepositoryFactory and configuration bits are relatively new and unfortunately right now don't contain a way to share a single DbContext, but I'll be adding that as a feature request and just need to think of the best way to make it happen.

With that being said, here is how I would handle it right now. Instead of using the RepositoryFactory you can just hard-code using a Ef5Repository until we implement this new feature. The first parameter in the constructor for Ef5Repository is a DbContext so you would pass your the same one into both repositories.

Not sure if you are using an IOC container like StructureMap, but if so you can set that up to handle creating a single DbContext for each thread or .NET request if it's a web application.

The StructureMap config would look like this:

        // Hybrid (once per thread or ASP.NET request if you’re in a web application)
        For<DbContext>()
           .HybridHttpOrThreadLocalScoped()
           .Use<MyEntities>()
           .Ctor<string>("MyContainer").Is(entityConnectionString);

Then your PersonManager would look like:

using SharpRepository.Repository;

public class PersonManager()
{

    private IRepository<Domain.PersonIdentifier, int> personIdentifierRepository;
    private IRepository<Domain.NextNumber, string> nextNumberRepository;

    public PersonManager(DbContext dbContext)
    {
        this.personIdentifierRepository = new Ef5Repository<Domain.PersonIdentifier, int>(dbContext);
        this.nextNumberRepository = new Ef5Repository<Domain.NextNumber, string>(dbContext);

    }

}

Unfortunately at this point you are hard-coding the type of the repository and don't get the benefits of the configuration file, but we'll get that feature in there soon. Thanks.

Update for SharpRepository version 1.2

Version 1.2 of SharpRepository (released on 3/14) fixes this issue. Now you can tell SharpRepository what IoC container you are using and it will use that to create the DbContext. This allows you to control the life-cycle of your DbContext and share it across multiple repositories.

First step is to get the NuGet package for the IoC container you are using. Search NuGet for SharpRepository.Ioc and you'll see the 5 IoC packages that we've created and are handled out of the box (Autofac, Ninject, StructureMap, Unity and Windsor), you can always create your own if you are using a different IoC that we don't cover right now.

Once that is installed you will need to set the RepositoryDependencyResolver in your App_Start code, Global.asax or bootstrapper code so it runs on application start. Here is how you would do it if using StructureMap.

RepositoryDependencyResolver.SetDependencyResolver(new StructureMapDependencyResolver(ObjectFactory.Container));

I am telling it to use StructureMap and pass in the Container. Then you just have to make sure the IoC is setup and knows how to handle a request for a DbContext. (see above for an example of that using the ASP.NET request life-cycle in StructureMap)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top