How DbMigrator works
I have code that instantiates a new DbMigrator(new Configuration())
Configuration is a custom extension of DbMigrationsConfiguration<T>, where T is DbContext
So within Configuration, there is a ContextType, which is equal to <T>.
When DbMigrator is instantiated, it attempts to create an instance of the <T> DbContext. It will either try to use an Empty Constructor on the <T> Context, or it will attempt to look for an implementation of IDbContextFactory<...> where ... is the actual type of , but not generic T.
How DbMigrator Doesn't Work
The problem is, the assembly instantiating DbMigrator has no access to the specific typed IDbContextFactory<...> that it needs to discover. Also, my DbContext has no default constructor, and I don't want it to. So I receive the exception The target context '...' is not constructible.
The thing that bothers me is, at the point I am instantiating DbMigrator, I already have an instance (or may already be within an instance) of the DbContext I am migrating. Also, I have access to a generic IDbContextFactory<T> that is not discoverable by DbMigrator's internals, but I'd be happy to provide it an instance.
The Question
So how do I tell DbMigrator to either just use my Context instance, or use an instance of a IDbContextFactory I specify? When it relies on its magic juju behind the scenes to try to discover these things (presumably using reflection/ServiceLocation) it is failing.
My Situation
Within one AppDomain, I am using n Contexts. I'd like to say one, but it's typically two, and may be more than that. So any solution that relies on a single app/web config property, or an attribute decorator, which points to a single DbConfiguration or ConnectionFactory won't work for me. Because there can only be one per AppDomain and, unless I could configure it based contextually on which Context I'm needing at the time, it is futile. So there's wiggle room there, but I dunno.
Also, there may be some juju I don't understand about EF relating to the base constructor. But I don't believe passing a DbConnection into the constructor instead of a nameOrConnectionString would work. It is still not an empty constructor. But if there's something EF does to search for constructors with that, and how to utilize it, that MIGHT work.
Related
Looking at some of the MVC examples online, I've see that typically in a controller the DbContext variable is declared as a private member variable (i.e. global) and accessible to all the methods.
But, I recently came across an article on ASP.NET Identity, and noticed in the controller, the DbContext is declared within each method (that requires it).
Is there a security benefit to this approach? Perhaps limit the lifespan of the security object(s) for better overall security?!?!
If not, then I see the first approach being more efficient, where the database context is instantiated upon the controller loading.
Below is all I could find about DbContext, but nothing to really answer my question.
DbContext declaration - Framework 4.1 - MVC 3.0
MVC, DbContext and Multithreading
On every request, a new instance of the controller is constructed. Therefore, for all intents and purposes, it does not really matter whether the dbcontext is instantiated in the constructor vs encapsulated in any given method.
Aside from a style choice, reasons to declare and contain a dbcontext in a given method is that:
Methods that do not need it will not instantiate the context, eliminating the overhead (if there is any). This can also be accomplished using a lazy initialization pattern.
The context is disposed of immediately as soon as a method is done with it, rather than at the end of the request. Generally this should not be a concern though; usually if users are waiting around for longer than a few seconds you have a bigger problem.
Different methods use different contexts.
Among others, some reasons to declare a single context and instantiate it once:
You have only one place that instantiates a context rather than many. In a typical application, most pages will need some information from the database anyway.
Methods that call other methods will not each hold on to their own instance of a context object.
You can create a base controller class that by default creates a dbcontext object, allowing you to be DRY in all inherited controllers.
Answer from #Ic. is pretty good. I wanted to add that if you need to pass information from your Request into your DbContext constructor then you need to create the instance of your DbContext inside your action methods. The reason is the Request object will be null till the control enters your action method.
More information: I had a need to build connection string dynamically depending on the location of the user. I saved the location as a cookie that I accessed through Request object. I had a valid Request inside the action method but it was null inside the constructor or at the class level properties of the controller.
I'm building a relatively simple webapp in ASP.NET MVC 4, using Entity Framework to talk to MS SQL Server. There's lots of scope to expand the application in future, so I'm aiming for a pattern that maximises reusability and adaptability in the code, to save work later on. The idea is:
Unit of Work pattern, to save problems with the database by only committing changes at the end of each set of actions.
Generic repository using BaseRepository<T> because the repositories will be mostly the same; the odd exception can extend and add its additional methods.
Dependency injection to bind those repositories to the IRepository<T> that the controllers will be using, so that I can switch data storage methods and such with minimal fuss (not just for best practice; there is a real chance of this happening). I'm using Ninject for this.
I haven't really attempted something like this from scratch before, so I've been reading up and I think I've got myself muddled somewhere. So far, I have an interface IRepository<T> which is implemented by BaseRepository<T>, which contains an instance of the DataContext which is passed into its constructor. This interface has methods for Add, Update, Delete, and various types of Get (single by ID, single by predicate, group by predicate, all). The only repository that doesn't fit this interface (so far) is the Users repository, which adds User Login(string username, string password) to allow login (the implementation of which handles all the salting, hashing, checking etc).
From what I've read, I now need a UnitOfWork class that contains instances of all the repositories. This unit of work will expose the repositories, as well as a SaveChanges() method. When I want to manipulate data, I instantiate a unit of work, access the repositories on it (which are instantiated as needed), and then save. If anything fails, nothing changes in the database because it won't reach the single save at the end. This is all fine. My problem is that all the examples I can find seem to do one of two things:
Some pass a data context into the unit of work, from which they retrieve the various repositories. This negates the point of DI by having my Entity-Framework-specific DbContext (or a class inherited from it) in my unit of work.
Some call a Get method to request a repository, which is the service locator pattern, which is at least unpopular, if not an antipattern, and either way I'd like to avoid it here.
Do I need to create an interface for my data source and inject that into the unit of work as well? I can't find any documentation on this that's clear and/or complete enough to explain.
EDIT
I think I've been overcomplicating it; I'm now folding my repository and unit of work into one - my repository is entirely generic so this just gives me a handful of generic methods (Add, Remove, Update, and a few kinds of Get) plus a SaveChanges method. This gives me a worker class interface; I can then have a factory class that provides instances of it (also interfaced). If I also have this worker implement IDisposable then I can use it in a scoped block. So now my controllers can do something like this:
using (var worker = DataAccess.BeginTransaction())
{
Product item = worker.Get<Product>(p => p.ID == prodName);
//stuff...
worker.SaveChanges();
}
If something goes wrong before the SaveChanges(), then all changes are discarded when it exits the scope block and the worker is disposed. I can use dependency injection to provide concrete implementations to the DataAccess field, which is passed into the base controller constructor. Business logic is all in the controller and works with IQueryable objects, so I can switch out the DataAccess provider object for anything I like as long as it implements the IRepository interface; there's nothing specific to Entity Framework anywhere.
So, any thoughts on this implementation? Is this on the right track?
I prefer to have UnitOfWork or a UnitOfWorkFactory injected into the repositories, that way I need not bother it everytime a new reposiory is added. Responsibility of UnitOfWork would be to just manage the transaction.
Here is an example of what I mean.
Suppose I register some instance in OpenRasta's dependency resolver using
resolver.AddDependencyInstance(IInterface, instance, DependencyLifetime.Singleton)
Now if I want to swap that instance later, say to reread fresh data from the db, is another call to resolver.AddDependencyInstance the right thing to do?
Checking the InternalDependencyResolver implementation, it seems to be fine. However I'm asking because the behavior is not defined (in openrasta's sources, where I checked), and the method prefix "Add" is suggestive of different behavior.
I wouldn't use Singleton if you have to swap the instance at some point.
Use DependencyLifetime.Transient and have a constructor injection in the class where you need the new instance
I'm new to this IoC and DI business- I feel like I get the concept if you are passing along objects that are of a global scope, but I don't get how it works when you need to pass around an object that is of a specific logical state. So, for instance, if I wanted to inject a person object into a write file command object- how would I be able to choose the correct person object dynamically? From what I have seen, I could default construct the object, but my disconnect is that you wouldn't use a default person object, it would need to be dynamic. I assume that the IoC container may just maintain the state of the object for you as it gets passed around, but then that assuems you are dealing in only one person object because there would be no thread safety, right? I know I am missing something, (maybe something like a factoryclass), but I need a little more information about how that would work.
Well, you can always inject an Abstract Factory into your consumer and use it to create the locally scoped objects.
This is sometimes necessary. See these examples:
MVC, DI (dependency injection) and creating Model instance from Controller
Is there a pattern for initializing objects created via a DI container
Can't combine Factory / DI
However, in general we tend to not use DI for Entities, but mostly for Services. Instead, Entities are usually created through some sort of Repository.
When you construct an service object (e.g. WriteFileService), you inject into it things it needs internally to complete it's job. Perhaps it needs a filesystem object or something.
The Person object in your example should be passed to the service object as a parameter to a method call. e.g. writeFileService.write(person)
I know some DI frameworks support this (e.g. Ninject), but I specifically want to know if it's possible with Autofac.
I want to be able to ask an Autofac container for a concrete class, and get back an instance with all appropriate constructor dependencies injected, without ever registering that concrete class. I.e., if I never bind it explicitly, then automatically bind the concrete class to itself, as if I had called builder.Register<MyClass>();
A good example of when this would be useful is ViewModels. In MVVM, the layering is such that only the View depends on the ViewModel, and that via loose typing, and you don't unit-test the View anyway. So there's no need to mock the ViewModel for tests -- and therefore there's no reason to have an interface for each ViewModel. So in this case, the usual DI pattern of "register this interface to resolve to this class" is unnecessary complexity. Explicit self-binding, like builder.Register<MyClass>();, also feels like an unnecessary step when dealing with something as straightforward as a concrete class.
I'm aware of the reflection-based registration example in the Autofac docs, but that's not to my taste either. I don't want the complexity (and slowness) of registering every possible class ahead of time; I want the framework to give me what I need when I need it. Convention over configuration, and all that.
Is there any way to configure Autofac so it can say "Oh, this is a concrete type, and nobody registered it yet, so I'll just act like it had been registered with default settings"?
builder.RegisterTypesMatching(type => type.IsClass)
If you look at the source you will see that RegisterTypesMatching (and RegisterTypesFromAssembly) is NOT DOING ANY REFLECTION. All Autofac is doing in this case is registering a rule that accepts a type or not. In my example above I accept any type that is a class.
In the case of RegisterTypesFromAssembly, Autofac registers a rule that says "if the type you're trying to resolve have Assembly == the specified assembly, then I will give you an instance".
So:
no type reflection is done at register time
any type that matches the criteria will be resolved
Compared to register the concrete types directly, this will have a perf hit at resolve time since Autofac will have to figure out e.g. constructor requirements. That said, if you go with default instance scope, which is singleton, you take the hit only the first time you resolve that type. Next time it will use the already created singleton instance.
Update: in Autofac 2 there is a better way of making the container able to resolve anything. This involves the AnyConcreteTypeNotAlreadyRegistered registration source.
what about:
builder.RegisterTypesFromAssembly(Assembly.GetExecutingAssembly());
no reflection is done, as Peter Lillevold points out.