Use interface between model and view in ASP.NET MVC - asp.net-mvc

I am using asp.net MVC 2 to develop a site. IUser is used to be the interface between model and view for better separation of concern. However, things turn to a little messy here. In the controller that handles user sign on: I have the following:
IUserBll userBll = new UserBll();
IUser newUser = new User();
newUser.Username = answers[0].ToString();
newUser.Email = answers[1].ToString();
userBll.AddUser(newUser);
The User class is defined in web project as a concrete class implementing IUser. There is a similar class in DAL implementing the same interface and used to persist data. However, when the userBll.AddUser is called, the newUser of type User can't be casted to the DAL User class even though both Users class implementing the interface (InvalidCastException).
Using conversion operators maybe an option, but it will make the dependency between DAL and web which is against the initial goal of using interface.
Any suggestions?

You should have a project which handles dependency injection.
This project references your Domain project (where IUserBll is defined), and the project which has the DLL implementation. So your MVC project will reference the dependency injection project and given a particular interface, ask the DI for an implementation of it.
Have a look at StructureMap or Castle Windsor.
//Global.asax
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
}
//Dependency Injection Project:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType != null)
{
return (IController)ObjectFactory.GetInstance(controllerType);
}
return null;
}
}
That way your controller can look more like:
public class SomeController
{
private IUserBll _repository;
public SomeController(IUserBll repository)
{
_repository = repository;
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(Someform f)
{
...
_repository.AddUser(...);
}
}
When you use a StructureMap controller factory for example, MVC will get the dependencies into your controller behind the scenes.

Related

How to decorate an ASP.NET MVC controller with Simple Injector

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.

Using Ninject dynamically to connection to different databases

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.

EF Context Management

What is the best way to manage the context of Entity Framework when using MVC application?
I am using a Repository/Service pattern.
Edit
After looking through some of these questions: stackoverflow.com/users/587920/sam-striano, I am more confused then before. Some say use the context per repository, but wht if I want to use multiple repositories in one controller method?
And to follow good separation design, how do you use UnitOfWork in the MVC app with out making it dependent on EF? I want to be able to unit test my controllers, model, services, etc. using a mock context?
Use a Dependency Injector/Inversion of Control framework like:
Ninject
Autofac
StructureMap
Unity
Using an IoC container, you can tell it how to manage a single data context (most commonly, per request). When you set the data context to per request, the container will auto-magically give any class that needs a data context the same data context per request.
Here is a good article on setting up Ninject.
What your code will most likely end up looking like, assuming you're using a generic repository:
Ninject Module:
public class NinjectRegistrationModule : NinjectModule
{
public override void Load()
{
Bind<MyDataContext>().ToSelf().InRequestScope();
Bind(typeof(RepositoryImplementation<>)).ToSelf().InRequestScope();
}
}
Generic Repository:
public RepositoryImplementation<T> : IRepository<T> where T : class
{
MyDataContext _dataContext;
public RepositoryImplementation<T>(MyDataContext dataContext)
{
_dataContext = dataContext;
}
// bunch of methods that utilize _dataContext
}
Service Class:
public class MyServiceClass
{
IRepository<SomeEntity> _someEntityRepository;
public MyServiceClass(IRepository<SomeEntity> someEntityRepository)
{
_someEntityRepository = someEntityRepository;
}
// do stuff with _someEntityRepository = someEntityRepository;
}
Controller:
public class MyController
{
MyServiceClass _myServiceClass;
public MyController(MyServiceClass myServiceClass)
{
// Ninject will auto-magically give us a myServiceClass
// which will Ninject will inject a repository into MyServiceClass's constructor
_myServiceClass = myServiceClass;
}
public ActionResult MyAction()
{
// use _myServiceClass to do stuff
return View();
}
}
If your functionality is straight forward, then you should create a new ObjectContext in each Repository. They are cheap to instantiate.
If this creates a conflict, you can use a Unit of Work pattern as was suggested in the comment.
I would advise that you be extremely cautious when integrating an ObjectContext or DataContext with a DI container. Many do not use the appropriate scope for their life cycle by default.

NInject and MVC 3 - Should I use DependencyResolver instead of [Inject] attribute?

Recently I moved to MVC 3 and Ninject 2. In most of the code, I use constructor injection, but there are some places, where I had to use Inject attribute. Ninject 2 registers its own IDepencyResolver interface. I don't like DependencyResolver class being part of System.Web.Mvc namespace, because its function is not really strictly related to MVC, but now, when it is there, I can do
public SomeClass
{
public IUserService UserService { get; set; }
public SomeClass()
{
UserService = DependencyResolver.Current.GetService<IUserService>();
instead of
public SomeClass
{
[Inject]
public IUserService UserService { get; set; }
so I don't have to reference Ninject namespace in my classes. Should DependencyResolver be used like that?
I use property injection only for dependencies that are not required for the proper working of the class but could add some functionality if the user sets them. Example of such functionality is logging. So you could have a property which represents a logger where the user can supply his own implementation and if he doesn't the class continues to work normally but it simply doesn't log.
For everything else I use constructor injection. This way you indicate to the consumer that this class has a required dependency on some other service.
So to answer your question about the property injection I would simply have:
public SomeClass
{
public IUserService UserService { get; set; }
public void SomeMethodWhichDoesntEnforceUserService()
{
if (UserService != null)
{
// Provide some additional functionality
}
}
}
and if your class cannot function properly without the user service:
public SomeClass
{
private readonly IUserService _userService;
public SomeClass(IUserService userService)
{
_userService = userService;
}
public void SomeMethodWhichRequiresTheService()
{
_userService.DoSomething();
}
}
So in both cases no reference to any DI specifics. That's what Inversion of Control is all about.
First question I would ask is why you can not perform constructor injection of the IUserService into SomeClass? It may indicate an issue with the design.
To avoid direct reference to the DependencyResolver you could implement some form of abstraction of a Service Locator over the DI framework, e.g. CommonServiceLocator, but as the answer to this question indicates, such abstractions shouldn't be necessary when doing DI correctly. Instead you should adjust the design of the application.
I believe the ninject.web.mvc version for mvc3 now supports constructor injection on filter attributes. Have you tried it?

Where does my CRUD LINQ Code Go? ASP.NET MVC

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.

Resources