i'm just starting out with asp.net mvc. It's a long way before you can really get to a live project. At the moment i'm working to build a blog using the asp.net mvc unleashed book.
However, i don't understand the 2 constructors in the BlogController (see question below)
Thx...
FIRST
The BlogController has a private variable '_repository'
Private _repository As BlogRepositoryBase
Public MustInherit Class BlogRepositoryBase
'blog entry methods
Public MustOverride Function ListBlogEntries() As List(Of BlogEntry)
Public MustOverride Sub CreateBlogEntry(ByVal BlogEntryToCreate As BlogEntry)
Public MustOverride Function QueryBlogEntries() As IQueryable(Of BlogEntry)
End Class
The BlogRepositoryBase gets inherited by EntityFrameworkBlogRepository _
The EntityFrameworkBlogRepository connects with BlogDBEntities
NEXT
The controller has 2 constructors 'new' and 'new with a parameter'
Public Sub New()
Me.New(New EntityFrameworkBlogRepository())
End Sub
Public Sub New(ByVal repository As BlogRepositoryBase)
_repository = repository
End Sub
QUESTIONS
What's going on with the constructors, i don't get that
How can a class of type 'EntityFrameworkBlogRepository' be passed to 'sub new' as BlogRepositoryBase? Isn't that another type?
The default constructor is calling the constructor with a parameter with a new instance of a particular type of BlogRepositoryBase class. EntityFrameworkBlogRepository must derive from this base class. The reason that you specify the base class (I would have used an interface, but I digress) is so in your tests you can specify a different type of repository -- one, perhaps, that doesn't even connect to a database by instantiating it directly via the non-default constructor. The framework wiil always use the default constructor, thus you have to both provide it and provide a suitable implementation of the repository using it.
FWIW -- this is how I would do it (in C# -- my brain isn't working well enough to translate into VB, yet).
protected IBlogRepository Repository { get; set; }
public BlogController() : this( null ) {}
public BlogController( IBlogRepository repository )
{
this.Repository = repository ?? new EntityFrameworkBlogRepository();
...
}
Tested as
public void Test()
{
var repository = MockRepository.GenerateMock<IBlogRepository>();
var controller = new BlogController( repository );
...
repository.VerifyAllExpectations();
}
EntityFrameworkBlogRepository is derived from BlogRepositoryBase
The 'magic' in the constructors is called Dependency Injection. (Wiki has more on that here.) In short, it is a way of making your code more maintainable and testable by passing it it's dependencies ... if you change the repository type you need not rip out most of your code.
Kindness,
Dan
Coding custom IControllerFactory or DefaultControllerFactory inherits class. And SetControllerFactory global.asax.
Haaked becomes reference very much.
TDD and Dependency Injection with ASP.NET MVC
Related
I am making a website using ASP.NET MVC and an onion architecture. I have the following architecture:
Domain : Entities / Domain Interfaces
Repository : Generic repository (for now) using Entity Framework Code First Approach
Service : Generic Service that calls the Repository
MVC
Now I am trying to create a method in my controller to start testing the methods I have implemented in Repository and Service, and I am having a hard time as to what I am allowed to create in this controller. I want to test a simple Get method in the Repository, but to do that I need GenericService object and GenericRepository object in my controller. To demonstrate what I mean here's a snippet of my GenericRepository(I will skip the interfaces):
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly PrincipalServerContext context;
private DbSet<T> entities;
public Repository(PrincipalServerContext context)
{
this.context = context;
entities = context.Set<T>();
}
}
Now my GenericService:
public class GenericService<T> : IGenericService<T> where T : class
{
private IRepository<T> repository;
public GenericService(IRepository<T> repository)
{
this.repository = repository;
}
public T GetEntity(long id)
{
return repository.Get(id);
}
}
And finally, my question, am I allowed to create these objects in my controller as follows (using my dbcontext called PrincipalServerContext):
public class NavigationController : Controller
{
private IGenericService<DomainModelClassHere> domainService;
private IGenericRepository<DomainModelClassHere> domainRepo;
private PrincipalServerContext context;
public ActionResult MyMethod(){
context = new PrincipalServerContext();
domainRepo = new GenericRepository<DomainModelClassHere>(context);
domainService = new GenericService<DomainModelClassHere>(domainRepo);
if(domainService.GetEntity(1)==null)
return View("UserNotFound");//Just as an example
return View();
}
}
Is this allowed? According to Jeffrey Palermo, UI can depend on Service and Domain so I don't know about the Repository. Technically I am not using methods from repository, but I do need to add a reference to the project.
If I can't then how can I create a new GenericService if I don't have a GenericRepository? Is there a better way to instantiate my objects ?
EDIT I think the answer to my question resides in Startup.cs where I can put something like service.addScoped(typeof(IGenericRepository<>),typeof(GenericRepository<>));
but I 'm not sure about this, any ideas?
I'll answer this on my own if ever someone encounters the same problem. There are configuration methods we can use to create instances of classes when needed. In the Startup.cs file you have to add ConfigureServices(IServiceCollection services) method and inside there are several methods that can be applied to services to create these instances. For example you can use:
services.AddTransient(IGenericRepository, GenericRepository)
What is the difference between services.AddTransient, service.AddScope and service.AddSingleton methods in Asp.Net Core 1? (this link explains differences between methods).
AddTransient is good in my case because it creates an instance of an object through the whole lifespan of the application, which is what I need. This means UI is dependant on the rest of the solution, because Startup.cs needs to know about the Repositories as well as the Services.
A pretty good answer can be found here :Onion Architecture : Can UI depend on Domain.
As the subject says...this question is about setting up the correct structure for my project only. if you think there is a better place to ask this question then please advise.
I have a MVC 4 project using ET & repository pattern. I have DAL & UI layer at this point.
Currently i am using my DAL for data access and I created my Interfaces & ViewModels within my Data Access Layer. i have a feeling i am doing it wrong. here is my Sample Set up.
MY DAL LAYER (Which contains below Interface, Repo & ViewModel)
DAL.ViewModel
Public Class ProductSummaryViewModel
Property productGUID As Integer
Property productName As String
End Class
DAL.Interface (For Repostiory Pattern)
Public Interface IProductRepository
Property ProductIdentityID As Integer
Property ImageMainPath As String
End Interface
DAL.Products Repository
Public Class productsRepository
Implements IProductRepository
Private _db As websolutionsEntities = New websolutionsEntities()
Public Function AddProduct(ByVal prdSummary As ProductSummaryViewModel) As Boolean Implements IProductRepository.AddProduct
_db.AddProduct(prdSummary )
Return true
End Function
And here is my Controller
Private ProductRepoitory As DAL.IProductRepository
Sub New()
Me.new(New DAL.productsRepository())
End Sub
Sub New(ByVal repo As DAL.IProductRepository)
repo = ProductRepoitory
End Sub
Public Function AddItem(ByVal prd As DAL.ProductSummaryViewModel) As ActionResult
Dim test as boolean = DAL.ProductRepoitory.AddItem(prd)
End Function
My project will grow in near future, so I want to set it up properly, however I don't want to make it too complicated as well for others and myself. Please advise with your suggestions.
Your can divide your project like this:
CORE
Interfaces(Ex: IProductRepository)
Domain(Ex: Product)
DAL
ProductRepository
MVC
ViewModels or Models(Ex: ProductsSummaryViewModel)
Controllers(Ex: ProductsController)
Make folders like Interfaces, Domain under CORE. You probably already have a controller folder in MVC frontend project. You also probably already have a folder called Models, just use that for ViewModels. Any thing used just for display purposes like the ViewModel classes should just exist in the front end.
I have a repository like:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
private readonly IContext _db;
public Repository(IContext context)
{
_db =context;
}
...
In Global.asax I have setup the ninject as:
kernel.Bind<IContext>().To<Context>();
This is working fine in the app probably because I'm explicity instantiating by calling the constructor with a paramater. There are problems in the unit tests however.
Then in a unit test I have:
var mockUnitOfWork = new Mock<UnitOfWork>();
var mockProjectApprovalRepository = new Mock<Repository<ProjectApproval>>();
mockUnitOfWork.Setup(x => x.ProjectApprovalRepository).Returns(mockProjectApprovalRepository.Object);
On this last line I get the error:
Can not instantiate proxy of class: MyNamespace.Repository Could not find a parameterless constructor.
I'm confused by this because I thought the point of Ninject was I didn't need to specify a parameterless constructor. Shouldn't ninject have instantiated a Context and used the constructor with one parameter.
When you do new Mock<Repository<ProjectApproval>>(), you're asking Moq to construct the object. If you asked Ninject to construct it, it would do it.
Ninject doesn't magically step in wherever construction happens - new is still new.
In this case, you can use an overload of the Mock constructor wherein you specify extra args.
Note that its generally accepted that Ninject shouldnt be anywhere near anything remotely close to the any common definition of the term Unit Test.
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.
If you don't know what I'm talking about either go through the tutorial and try to add dependency Injection yourself or try your luck with my explanation of the problem.
Note: This problem isn't within the scope of the original tutorial on ASP.NET. The tutorial only suggests that the patterns used are dependency injection friendly.
The problem is basically that there is a dependency loop between the Controller, the ModelStateWrapper and the ContactManagerService.
The ContactController constuctor takes an IContactManagerService.
The ContactManagerService constructor takes an IContactManagerRepository (not important) and an IValidationDictionary (which ModelStateWrapper implements).
The ModelStateWrapper constructor takes a ModelStateDictionary (which is a property called "ModelState" on the controller).
So the dependency cycle goes like this: Controller > Service > ModelStateWrapper > Controller
If you try to add dependency injection to this, it will fail. So my question is; what should I do about it? Others have posted this question, but the answers are few, different, and all seem kinda "hack-ish".
My current solution is to remove the IModelStateWrapper from the IService constructor and add an Initialize method instead like this:
public class ContactController : Controller
{
private readonly IContactService _contactService;
public ContactController(IContactService contactService)
{
_contactService = contactService;
contactService.Initialize(new ModelStateWrapper(ModelState));
}
//Class implementation...
}
public class ContactService : IContactService
{
private IValidationDictionary _validationDictionary;
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
private void Initialize(IValidationDictionary validationDictionary)
{
if(validationDictionary == null)
throw new ArgumentNullException("validationDictionary");
_validationDictionary = validationDictionary;
}
//Class implementation...
}
public class ModelStateWrapper : IValidationDictionary
{
private readonly ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
//Class implementation...
}
With this construct I can configure my unity container like this:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
Unfortunately this means that the "Initialize" method on the service has to be called manually by the controller constructor. Is there a better way? Maybe where I somehow include the IValidationDictionary in my unity configuration? Should I switch to another DI container? Am I missing something?
As a general consideration, circular dependencies indicate a design flaw - I think I can safely say this since you are not the original author of the code :)
I wouldn't consider an Initialize method a good solution. Unless you are dealing with an add-in scenario (which you aren't), Method Injection is not the right solution. You have almost already figured that out, since you find it unsatisfactory that you need to manually invoke it because your DI Container can't.
Unless I am entirely mistaken, the ContactController doesn't need the IValidationDictionary instance before its Action methods are being invoked?
If this is true, the easiest solution would probably be to define an IValidationDictionaryFactory interface and make the ContactController constructor take an instance of this interface.
This interface could be defined like this:
public interface IValidationDictionaryFactory
{
IValidationDictionary Create(Controller controller);
}
Any Action method on the controller that needs an IValidationDictionary instance can then invoke the Create method to get the instance.
The default implementation would look something like this:
public class DefaultValidationDictionaryFactory : IValidationDictionaryFactory
{
public IValidationDictionary Create(Controller controller)
{
return controller.ModelState;
}
}
How about slightly changing/improving the design to something like this: http://forums.asp.net/t/1486130.aspx
Each controller has a virtual method Initialize to do stuff like that.
I think there is no better way because the IValidationDictionary is an abstraction layer between you current request/controller/modelstate and the IContactService. Injecting controllers modelstate into the service and then injecting the service into the controller is simply impossible using constructor injection. One has to be first.
May be there is a way using property injection? But I think this will be complicated too.