Autofac - Use the same DbContext across multiple repositories - autofac

I have a desktop app using Autofac. The framework I'm using doesn't provide hooks for dependency injection and thus the view models are instantiated using the service locator pattern.
One of my view models has two repositories that it uses. The repositories both take a single object, with is the applications DbContext.
Autofac instantiates two DbContext instances - one for each repository. The two repositories should use the same DbContext instance.
The service locator is implemented as:
ServiceLocator.Current = new ServiceLocator((type) =>
{
var resolved = _container.Resolve(type);
return resolved;
});
Where _container is an IContainer instance built thusly:
var builder = new ContainerBuilder();
/* snip */
_container = builder.Build();
How can I have Autofac use the same DbContext for all dependencies when creating the instance of the view model?
I definitely don't want a singleton context - subsequent instantiations of the view model, or other view models, should yield a different DbContext.

You could employ custom lifetime scopes for that (https://autofac.readthedocs.io/en/latest/lifetime/working-with-scopes.html).
The idea is to register DbContext with InstancePerLifetimeScope() and then create a lifetime scope for every instance of view model. Autofac would create a single instance of DbContext per lifetime scope (and, thus, per view model).
The issue would be that custom lifetime scopes require manual disposal so you'd need to take care of LifetimeScope.Dipose() call after your view model is no longer needed.

Related

How to inject dbcontext with StructureMap and WebApi2

I would like to inject my dbcontext into my services in web api 2 project. But I’m a little unsure of how to do that. I've read through the docs but lifecycles, scopes, requests, nested containers...they all leave me a little unsure. I have pieced together the following code from my best understanding. After installing the Nuget package StructureMap.WebApi2, I proceeded to update SM from v3 to v4, as well as the SM.MVC5 from v3 to v4.
The following code appears to have the desired effect of using one dbcontext per http request (I think that's what i want...i'm so confused about scopes) so that the same dbcontext is shared for all services during a users transaction, and then disposed when the transaction (http request) is closed. But appearances are not always right.
IoC.cs
public static IContainer Initialize()
{
var container = new Container(_ =>
{
_.AddRegistry<DefaultRegistry>();
_.ForConcreteType<MyDbContext>().Configure.ContainerScoped();
});
DomainEvents.Initialize(container);
return container;
}}
DefaultRegistry.cs:
public DefaultRegistry()
{
var mapperConfig = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new Common.Map.MapProfile());
cfg.CreateMissingTypeMaps = true;
});
var mapper = mapperConfig.CreateMapper();
For<IMapper>().Use(() => mapperConfig.CreateMapper());
For<MyDbContext>().Use(()=> new MyDbContext());
Scan(
scan =>
{
scan.AssemblyContainingType<ServiceBase>();
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.ConnectImplementationsToTypesClosing(typeof(IHandle<>));
});
}
The Nuget package StructureMap.WebApi2 created some other files for wiring up resolution and nested containers, but i'm leaving them out of this question for the sake of brevity.
Have a look at the Mehdime DbContext Scope Factory / Locator: https://github.com/mehdime/DbContextScope and he has a bit of a run-down of it on his blog. (link in the project description.) There are forks off there updated to the latest EF versions.
I've found it to be an excellent unit of work wrapper for EF contexts without having to worry about injecting or passing around those contexts directly.
The trouble with IoC containers and constructor injection is that if you register your DBContext it means that it's hard to work with things like a unit of work within the scope of a request without it essentially being the entire scope of the request. The DbContext Scope solves this by having you register a Scope Factory and a Scope Locator in your Container. Code controlling the Scope (unit of work) will use the Scope Factory to initialize a context scope for your DbContexts. Code operating with DbSets etc. in a DbContext use the ContextScopeLocator to get their UoW /w it's DbContext & sets.

How to create a library exposing named configured singletons generated at runtime with Dagger 2?

I'm considering migrating to Dagger 2 some libraries. This library expose a configurable client, each configuration can be named and later retrieved in a singleton fashion.
Let me show a pseudo-code of how the library works from the user perspective:
// initialization
ClientSDK clientA = new ClientSDK.Builder()
.configuration().attributes().here()
.apiKey("someString") // set api key / credentials
.build();
LibraryAuthenticationManager customAuthManager = new MyCustomAuthenticationManager();
ClientSDK clientB = new ClientSDK.Builder()
.configuration().attributes().here()
.apiKey("someStringElse")
.customAuthManager(customAuthManager) // override some default
.baseApiUrl("https://custom.domain.com/and/path") // override some default setting
.build();
ClientSDK.setSingleton("clientA", clientA);
ClientSDK.setSingleton("clientB", clientB);
And when I need an instance elsewhere:
// usage everywhere else
ClientSDK clientB = ClientSDK.singleton("clientB");
clientB.userManager(); // "singleton" using the configuration of clientB
clientB.subscriptionsManager(); // "singleton" using the configuration of clientB
clientB.currentCachedUser(); // for clientB
clientB.doSomething(); // action on this instance of the ClientSDK
ClientSDK instances are created by the user of the library and the ClientSDK statically keep a map of singletons associated to the name.
(The actual behavior of the SDK is slightly different: the naming is automatic and based on a mandatory configuration parameter.)
It's like I have lot of singleton classes with a single point of entry (the ClientSDK) but since I can have multiple configuration of the ClientSDK each with his own singletons instances this are not really singletons.
If I would try write a library like that with Dagger 2 I would do something like:
class ClientSDK {
#Inject SDKConfiguration configuration;
#Inject LibraryAuthenticationManager authManager;
...
}
The problem is that I need each instance of the ClientSDK to have its own configuration and authManager (and many other services) injected. And they need to be definable (the configuration) and overridable (the actual implementation) from the library user.
Can I do something like this with Dagger 2? How?
I've seen I can create custom Scopes but they are defined at compile time and the library user should be the one defining them.
(the library is an Android Library, but this shouldn't be relevant)
Thanks
It sounds like you should be creating stateful/configurable Module instances and then generating separate Components or Subcomponents for each ClientSDK you build.
public class ClientSDK {
#Inject SDKConfiguration configuration;
#Inject LibraryAuthenticationManager authManager;
// ...
public static class Builder {
// ...
public ClientSDK build() {
return DaggerClientSDKComponent.builder()
.configurationModule(new ConfigurationModule(
apiKey, customAuthManager, baseApiUrl)
.build()
.getClientSdk();
}
}
}
...where your ConfigurationModule is a #Module you write that takes all of those configuration parameters and makes them accessible through properly-qualified #Provides methods, your ClientSDKComponent is a #Component you define that refers to the ConfigurationModule (among others) and defines a #Component.Builder inner interface. The Builder is important because you're telling Dagger it can no longer use its modules statically, or through instances it creates itself: You have to call a constructor or otherwise procure an instance, which the Component can then consume to provide instances.
Dagger won't get into the business of saving your named singletons, but it doesn't need to: you can save them yourself in a static Map, or save the ClientSDKComponent instance as an entry point. For that matter, if you're comfortable letting go of some of the control of ClientSDK, you could even make ClientSDK itself the Component; however, I'd advise against it, because you'll have less control of the static methods you want, and will lose the opportunity to write arbitrary methods or throw exceptions as needed.
You don't have to worry yourself about scopes, unless you want to: Dagger 2 tracks scope lifetime via component instance lifetime, so scopes are very easy to add for clarity but are not strictly necessary if you're comfortable with "unscoped" objects. If you have an object graph of true singleton objects, you can also store that component as a conventional (static final field) singleton and generate your ClientSDKComponent as a subcomponent of that longer-lived component. If it's important to your build dependency graph, you can also phrase it the other way, and have your ClientSDKComponent as a standalone component that depends on another #Component.

Where does Unit Of Work belong w/ EF4, IoC (Unity), and Repository?

I see several questions relating somewhat to this, but I still can't find the answer I'm looking for, so I'm posting my question. If another question holds the answer (and I'm just not seeing it), please point me to it.
I'm trying to figure out where my UnitOfWork belongs -- and specifically, gets created -- when using EF4 and Unity with the Repository pattern.
Basically, I have a service that is used to implement my business logic. This service constructor takes in the repository, so the service gets injected with my repository. The service then uses the injected repository to carry out actions against the data store -- but I need to wrap these in a unit of work.
My unit of work, however, needs to be injected with the EF4 context (or, in my case, and interface of the context -- IObjectContext). And I'm not sure where the UoW should be created and injected w/ the context.
Here are the possible options I can think of, none of which seem ideal:
Include the UoW in the service constructor, thus having the service injected w/ the unit of work, which in turn is injected w/ my EF4 context. But this seems wrong because I don't want my UoW created on every instance of the repository.
Do an on-demand creation using container.Resolve to get an instance of the UoW, injecting my EF4 context. This seems excessive having to constantly hit the IoC container, rather than already having access to the UoW.
Inject the context directly into the service, allowing me to create a UoW(context). This seems bad since I've now exposed the context to the service, and this should be isolated to the repository.
So my question is, is one of these methods acceptable, or is there another method I'm not thinking of?
Thanks in advance.
There are probably several ways how to use this so I will describe one which I found useful.
Imho the place to define UoW is in Application logic - the logic which calls your business layer (business services). The reason for this is that UoW should represent logical business trasaction - application logic (or service facade in case of remote calls) defines what is logical transaction. So for example in MVC you can go with architecture where each controller action represents single UoW:
public class MyController : Controller
{
public MyController(IFirstService firstService, ISecondService secondService,
IUnitOfWork unitOfWork)
{ ... }
[HttpPost]
public ActionResult SomeAction(Model data)
{
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();
return RedirectToAction(...);
}
}
In this example my controller is depenent on two business services and action calls them both - UoW then save changes performed by both services. That is the reason why I think the UoW should be available in controller because if your application layer don't have access to UoW you can't compose (reuse) your logic from several service calls (because each probably calls its own SaveChanges).
Other approach is with service facade. Facade will be public interface of your business layer and it will hide service composition:
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();
In such case UoW will not be passed to controller but to service facade and service facade will be injected to controller. You will definitely use this approach if your business logic will be exposed over web service (or other remote technology).
The last problem which you have to deal with is passing UoW to services. Services as well as UoW are injected into controller (presenter, service facade or whatever) but in the same time UoW (or ObjectContext) must be injected into services so that internally used repositories can work with it. For this you need correct IoC lifetime manager so that it returns same instance for all injections within same "request". In case of web application you need PerHttpRequest lifetime manager (which you must implement by yourselves because Unity does not provide it).
One way is to manage this is to use the method described in http://mfelicio.wordpress.com/2010/02/07/managing-the-entity-framework-objectcontext-instance-lifetime-in-wcf-and-sharing-it-among-repositories/ That article implements the ContextManager for Wcf services. For ASP.NET app we could use something like this.
public class AspNetDBContextManager<TContext> : IDBContextManager
where TContext : IDBContext, new()
{
#region IDBContextManager Members
public IDBContext GetDBContext()
{
return this.GetOrCreateDbContext();
}
private IDBContext GetOrCreateDbContext()
{
if (HttpContext.Current == null)
{
throw new InvalidOperationException("Can be used only within ASP.NET applications");
}
string dbContextKey = string.Format("__AspNetDBCM__{0}__", HttpContext.Current.GetHashCode());
object dbContext = HttpContext.Current.Items[dbContextKey];
if (dbContext == null)
{
dbContext = new TContext();
if (dbContext != null)
{
HttpContext.Current.Items[dbContextKey] = dbContext;
}
}
return dbContext as IDBContext;
}
#endregion
}
public interface IDBContext
{
object Context { get; }
}
public interface IDBContextManager
{
IDBContext GetDBContext();
}

Using Entity Framework w/o Global State

I made a small test function for creating an Entity Framework Code-First DbContext instance directly connected to a SQL CE 4.0 file but I really don't like the global state approach. Isn't there a better way to do this, without using DbDatabase static properties?
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Database;
using System.Data.SqlServerCe;
public class SqlCeDb
{
public static T Instance<T>() where T: DbContext, new()
{
DbDatabase.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
DbDatabase.SetInitializer<T>(new DropCreateDatabaseAlways<T>());
return new T();
}
}
Dependency Injection is what a lot of people are doing. You write a class that has a dependency on DbContext (i.e. it's a constructor argument or a property decorated as a dependency), and the IoC (Inversion of Control) container will give you an instance of it when the class is created. Every IoC container I've worked with has a way of registering a single instance (instead of creating a new instance every time).
Popular IoC Containers:
StructureMap
Unity
Ninject
There are others, but these are the ones I see used most often.

StructureMap injected IContainer - where does it come from?

I have an ASP.Net MVC application and I am using StructureMap within MVC to glue the whole application together. There are some model classes that have heavyweight dependencies that are not used in all public methods, so I pass in an IContainer to the model constructor and use that to create the heavyweight dependencies on demand.
My question is where does the IContainer come from that is injected? Is it a reference to the one held centrally by MVC (it's logical parent) or is it a brand new one created and configured solely for this class?
The container injected into a constructor that has an IContainer parameter is the same container that is creating the instance of the class with the constructor.
Jeremy Miller has expressed this behaviour as "IContainer is injected into itself by default" in his blog post on NHibernate with StructureMap.
Couldn't you go with a factory model for creating those dependencies when needed in order to reduce your coupling to the container?
You could make your model take a Func as parameter and use SM's ability to autoinject those:
public class MyModel
{
Func<IHeavyDep> _heavyFactory;
public MyModel(Func<IHeavyDep> dependency)
{
_heavyFactory = dependency;
}
public void UsesHeavy()
{
var heavy = _heavyFactory();
heavy.DoMyStuff();
}
}