I have an MVC application using Ninject to connect to a single database. Now I need to support multiple databases. Currently, my global.asax.cs file has the following definition for ninject:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
//Using DI for controllers - use the Ninject custom controller factor
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory()); // Repository config is defined in ninject controller
}
And here is what my Ninject controller class looks like:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel kernel = new StandardKernel(new EriskServices());
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
if (controllerType == null)
return null;
return (IController)kernel.Get(controllerType);
}
private class EriskServices : NinjectModule
{
public override void Load()
{
Bind<IRisksRepository>().To<MySql_RisksRepository>()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["mydb1"].ConnectionString);
}
}
}
I also have a login page that handles user authentication. It is done through LDAP and does not require database connection.
My question is: Can I bind the ninject connectionString after the user authentication login page? The user would have a dropdown list for database they want to connect to, for example "mydb1" or "mydb2" or "mydb3". Each connection string would be defined in the web.config file.
Please help! Thank you!
No, you can't bind "after" - for one thing, web applications are stateless and you have no control over the order of events, but more importantly, Ninject modules define your IoC container and this configuration happens before almost anything else in the application or request lifecycle.
If you're saying that the user would pick this from a drop-down, then the act of choosing the repository is part of your application logic, not part of your IoC configuration. The way to deal with this is to create a factory interface. The implementation can be a thin wrapper around the Ninject kernel itself.
public interface IRisksRepositoryFactory()
{
IRisksRepository GetRepository(string name);
// Optional: add a GetRepositoryNames() method for populating dropdowns, etc.
}
public class NinjectRisksRepositoryFactory
{
private readonly IKernel kernel;
public NinjectRisksRepositoryFactory(IKernel kernel)
{
if (kernel == null)
throw new ArgumentNullException("kernel");
this.kernel = kernel;
}
public IRisksRepository GetRepository(string name)
{
return kernel.Get<IRisksRepository>(name);
}
}
For this particular implementation you'd want to make sure you use named bindings (although generally speaking you could also use the metadata system), and do each binding explicitly:
Bind<IRisksRepository>()
.To<MySqlRisksRepository>()
.InRequestScope()
.Named("mysql")
.WithConstructorArgument("connectionString", GetConnectionString("mydb1"));
Bind<IRisksRepository>()
.To<OracleRisksRepository>()
.InRequestScope()
.Named("oracle")
.WithConstructorArgument("connectionString", GetConnectionString("ordb1"));
Bind<IRisksRepositoryFactory>()
.To<NinjectRisksRepositoryFactory>();
It's also possible to do this without creating each binding explicitly, particularly if all targets are the same type (i.e. you only have a MySqlRisksRepository), by passing the connection string or related symbol as a parameter to the Get call and binding to a contextual method instead of a type - but I'd recommend against it, since it's really swimming against the current as far as DI in general goes.
One more thing: Don't worry that this resembles the "service locator" anti-pattern, because that's all it is - a superficial resemblance. When objects need to be able to create dependencies on the fly, creating special-purpose factories around the IoC container is the recommended solution, as it minimizes kernel exposure to a single class which could be easily replaced if you switched to a different framework.
Related
I want to use DI to manually inject an IDBConnection in my api controllers. I know I can put it in the constructor:
public MyController(IDBConnection cnn) { this._Connection = cnn; }
Or I could use the [FromServices] attribute:
[FromServices]
public IDbConnection _Connection { get; set; }
And I can use it in views like this:
#inject IDbConnection cnn
What I would really like to do would be to have it in a using, and have the DI open the connection so I could do something like this:
using (var cnn = Services.Inject<IDbConnection>()) {
// do something, don't worry about opening or closing
}
I'm declaring it like this:
services.AddTransient<IDbConnection>(x =>
{
string connectionString = Configuration.Get<string>(
"Data:DefaultConnection:ConnectionString");
return new SqlConnection(connectionString);
});
Should I create a class inheriting from SqlConnection that calls Open() in it's constructor? How can I access Configuration from there? I could create it like that to inject configuration or the connect string... Is using not required? Is there basically no overhead with just creating the instance so it wouldn't matter if some actions needed multiple connections to different databases?
I recommend that you create a service layer that your controller will depend on instead of directly accessing the db connection (and you won't have to this in your views #inject IDbConnection cnn). Your views should only declare the Model that your controller method returns and you will have nice intellisense support in the view pages.
public class ProductServices(){
public ProductServices(IDbConnection conn){
...
}
public List<Product> GetProducts(){
...
}
}
using is not required. As a rule of thumb, if the instance is created via IoC container (eg. Unity, Autofac, Ninject, etc), it should also be destroyed by the IoC container.
I'd like to apply some cross-cutting concerns to my MVC controllers. At the moment, this is implemented through an abstract base class, but as we are refactoring more of the code base to take advantage of dependency injection, I'm wondering if this is something Simple Injector can help me with through its decoration or interception facilities.
So I've attempted to create a pretty basic decorator:
public class ControllerDecorator : IController
{
private readonly IController _controller;
public ControllerDecorator(IController controller)
{
_controller = controller;
}
public void Execute(RequestContext requestContext)
{
// Do something of a cross-cutting nature here...
_controller.Execute(requestContext);
}
}
And in my composition root: container.RegisterDecorator<IController, ControllerDecorator>()
However, the code in my decorator's Execute method doesn't seem to ever get called. Is it because the MVC framework directly resolves my controller classes instead of going through IController? In that case, what can I do? What am I missing here?
In the default configuration, you can't apply decorators to controllers. The reason for this is that MVC's DefaultControllerFactory requests controllers by their concrete type. Because it requests a concrete type, Simple Injector is unable to apply a decorator; it has to assume that the caller needs this concrete type and has to therefore return this exact type (or a sub type).
To fix this, you will have to replace the default DefaultControllerFactory with a custom one:
public class SimpleInjectorControllerFactory : DefaultControllerFactory {
public IDictionary<Type, InstanceProducer> Producers { get; set; }
protected override IController GetControllerInstance(RequestContext rc, Type type) {
return (IController)this.Producers[type].GetInstance();
}
}
Next, in your bootstrapper, you'll have to replace the call to RegisterMvcControllers with the following:
var controllerTypes = SimpleInjectorMvcExtensions.GetControllerTypesToRegister(
container, Assembly.GetExecutingAssembly());
var controllerProducers = controllerTypes
.ToDictionary(type => type, type => CreateControllerProducer(container, type));
// Verify after creating the controller producers.
container.Verify();
ControllerBuilder.Current.SetControllerFactory(
new SimpleInjectorControllerFactory { Producers = controllerProducers });
The CreateControllerProducer method looks as follows:
private static InstanceProducer CreateControllerProducer(Container c, Type type) {
var producer = Lifestyle.Transient.CreateProducer(typeof(IController), type, c);
producer.Registration.SuppressDiagnosticWarning(
DiagnosticType.DisposableTransientComponent,
"MVC disposes the controller when the web request ends.");
return producer;
}
The crucial part is that the call to CreateProducer is supplied with typeof(IController); this allows Simple Injector to apply a decorator for IController.
This is it; now you can register your decorator for IController.
One warning though: with both Web API and the new ASP.NET core it is impossible to apply decorators to controllers. Both frameworks expect concrete types; they will break if you wrap the real controller. The preferred way with those frameworks to decorate controllers is through the OWIN pipeline. So this answer solely works with MVC 3, 4 and 5.
I'm ASP.NET MVC newbye and I'm learning and experimenting Enterprise design patterns: very interesting and helpful things indeed! But I keep missing something about the concept of disposing resources. To be more specific want to focus on the mechanism of controllerFactory which injects in the controller constructor an implementation of IFuncyRepository or IFuncyService or anyother kind of "resource" to be used in the controller (In my case I'm using StructureMap as IoC).
My question is WHERE / IF / HOW these injected resources get Disposed.
The book I'm following as guideline is ASP.NET Design Patterns and until now I can't get any explaination about this thing and also no clue becouse no class is structured implementing IDisposable. So looks like the resource disposing task gets done automagically somewhere (maybe in the IoC??).
Since I can't understand this, I cannot be sure about the performance of my application which leads to very annoying doubts!
Thanks in advance to anyone will reply or share my concern ;)
As a rule of thumb, the creator of a disposable object should also be the disposer of that same object. Thus, if you create an object graph from a custom IControllerFactory you should also use its ReleaseController for decommissioning.
Here's an example using Castle Windsor:
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;
public WindsorControllerFactory(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (IController)this.container.Resolve(controllerType);
}
public override void ReleaseController(IController controller)
{
this.container.Release(controller);
}
}
I am currently using the ASP.NET MVC framework on a project (pretty much my first time)
I am using Linq2SQL as my data model..
Where should i have this kind of code:
var entries = from e in db.sometable select e;
I currently have this kinda code in the controller and pass the data i get into the view..
is this ok?
if not how do i entend my linq2sql datamodel to include this kindof code?
Thanks
Daniel
To add what #Poco said, here's an example:
In Foo.Common.Repositories (inside the Foo.Common Project):
public interface IRepository<T>
{
IEnumerable<T> GetAll();
void Update(T entity);
void Add(T entity);
void Delete(T entity);
void Save();
}
public interface IUserRepository : IRepository<User>
{
void GetByCredentials(string username, string password);
}
The inside Foo.Data.Repositories (inside Foo.Data project):
public class UserRepository
{
// ... other methods/properties snipped.
public IEnumerable<User> GetAll()
{
// Where this.Users would be L2Sql or Code-First... or some other ORM.
return from u in this.Users orderby u.Name select u;
}
}
Then inside your actual Foo.Web:
public class UserController : Controller
{
private readonly IUserRepository userRepository;
public UserController(IUserRepository userRepository)
{
this.userRepository = userRepository;
}
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult List()
{
var users = this.userRepository.GetAll();
return this.View(users);
}
}
And inside your Global.asax you'd have Ninject or some other IoC container to resolve IUserRepository:
public static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUserRepository>().To<UserRepository>();
}
protected void Application_Start()
{
var kernel = new StandardKernel();
AreaRegistration.RegisterAllAreas();
MvcApplication.RegisterGlobalFilters(GlobalFilters.Filters);
MvcApplication.RegisterRoutes(RouteTable.Routes);
MvcApplication.RegisterServices(kernel);
// I'm using MVC3 here:
DependencyResolver.SetResolver(new NinjectResolver(kernel));
}
It's common to use the Repository pattern for MVC.
Typically, you define an interface, for instance, IProducts, and then, you implement this interface, calling you linq2sql code. Your controller will accept this interface as a parameter for the constructor, so that it depends on this interface, and not on a concrete class. Using a dependency injector, such as Ninject, will allow you to supply a concrete interface implementation to the constructor. This enables Unit Testing on you web app, and also adds flexibility.
There's a really nice book, Pro ASP.NET MVC 2 Framework, that explains all that. I'm currently reading it, and I just love it.
Here's an example of how to implement the repository pattern
In addition to this I would implement an additional layer to handle your applications business logic and keep your controllers lightweight
It's fine to have Linq queries in controller methods.
If we're talking about separation of concerns, the idea is that your data layer (in this case, the repository(?) code that supplies you with db.sometable) decouples your logic code (controller methods in this case) from the datastore.
You query the data layer rather than the database, so you can change the underlying datastore and your controller code will still work.
Some would argue that it's better again to move as much logic code as you can out of the controllers and into your model code (see the first answer here), but it depends how far you want to go.
here's the default AccountController.cs that's generated by the framework.
public class AccountController : Controller
{
public IFormsAuthentication FormsAuth { get; private set; }
public IMembershipService MembershipService { get; private set; }
public AccountController()
: this(null, null)
{
}
public AccountController(IFormsAuthentication formsAuth, IMembershipService membershipService)
{
FormsAuth = formsAuth ?? new FormsAuthenticationService();
MembershipService = membershipService ?? new AccountMembershipService();
//---
}
This is easy to understand.
public AccountController(IFormsAuthentication formsAuth,
IMembershipService membershipService)
{
FormsAuth = formsAuth ?? new FormsAuthenticationService();
MembershipService = membershipService ?? new AccountMembershipService();
}
What's this? What's its purpose? Is it particular to the Account Controller or is it a requirement for other controllers? and, why should I incorporate it in my project?
public AccountController()
: this(null, null)
{
}
They seem to use this type of constructors in two other places.
Thanks for helping
This is actually an implemenation of the Bastard Injection anti-pattern.
The idea is that Constructor Injection is supported to allow Dependency Injection (DI), while still providing a default constructor for default behavior.
It's really not necessary to have the default constructor, but if you omit it, you must supply a custom IControllerFactory, as the DefaultControllerFactory assumes that all Controllers have default constructors.
ASP.NET MVC is built with DI in mind, but I guess that to keep it simple, the Bastard Injection pattern was used for the project template to avoid forcing a specific IControllerFactory upon developers.
If you use a DI framework (like Unity) and you active your controllers via the container, it might not find the dependencies and use the default constructor (in this case).
If you would like use use generics, something like ... where T : IController, new() you will need a default constructor.
Another reason for having a default (no parameter) constructor is for Reflection.
The classes in the System.Reflection namespace, together with Type, allow you to obtain information about loaded assemblies and the types defined within them, such as classes, interfaces, and value types. You can also use reflection to create type instances at run time, and to invoke and access them.
There might be times where you need to create a temporary object of that type in order to reflect over it's properties or methods, but don't want or need the overhead of creating a real object - especially if that entails accessing a database or remote service for example.