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.
Related
I am using a single database design for 3 different SQL Server locations (production, backup, master). The design is simple, shown below for the production location:
Public Class ProductionDbContext
Inherits DbContext
Public Sub New()
MyBase.New("ProductionDbConnection")
End Sub
Public Sub New(connectionString As String)
MyBase.New(connectionString)
End Sub
Public Property Tables As DbSet(Of Table) 'Table includes a List(Of Topic)
Public Property Topics As DbSet(Of Topic) 'for direct access to Topics when needed
End Class
I have initially coded 3 separate contexts according to what's above, so:
Public Class ProductionDbContext
Public Class BackupDbContext
Public Class MasterDbContext
When I access these contexts for various operations, I'd like to do something simple like:
Dim prodDb As New ProductionDbContext
Dim backupDb As New BackupDbContext
Dim masterDb As New MasterDbContext
Dim topicsList As New List(Of Topic)
LoadData(topicsList, prodDb) or
LoadData(topicsList, backupDb) or
LoadData(topicsList, masterDb)
And then LoadData is defined as something like (but this doesn't work):
Public Sub LoadData(ByRef topicsList As List(Of Topic), localContext As Object)
Dim thisTopicTable = localContext.Tables.Include("Topics").Where(Function(x) x.Property = "something").SingleOrDefault()
If thisTopicTable IsNot Nothing Then
topicsList = thisTopicTable.Topics.ToList()
End If
End Sub
This doesn't work because localContext is not defined properly to have access to the EF methods like .Where and so on.
I know my current design attempt is not correct, but I don't have the experience yet to know how I should have designed things so that the 3 different databases/dbContexts can be treated as similar objects and I don't have to "repeat myself" throughout the code.
There may be a better way to setup the 3 separate databases that I should have used, and that would be great to know (implied question 1), but I would still like to understand more deeply how I use the idea of a Type Object when passing parameters so the object can be coded in the new method the same way as the object being passed in (question 2). I don't really do a lot of that type of coding; most of my code is very type structured.
I did try to design an intermediate Class that inherits DbContext that could then be inherited by my 3 Classes listed above, but I quickly `lost the pursuit curve' on that.
I have an ASP.NET MVC application which uses MEF to implement a plugin framework. Plugins are separate DLLs that exist in the application's bin directory. Plugins usually export one or more controllers like this...
<Export(GetType(IController))>
<MYAPP_Interfaces.Attributes.MVCPluginMetadata(
"SomePlugin",
"A Description for the plugin",
"A Readable Name",
{"ScriptsForThePlugin.js"},
{"StylesForThePlugin.css"},
Enumerations.MVCPluginType.DataView,
"DefaultActionName")>
<PartCreationPolicy(CreationPolicy.NonShared)>
Public Class MyPluginController
Inherits System.Web.Mvc.Controller
<Import()>
Private m_objHost As IWebHost
... and so on.
This all works fine, the host app includes all controllers in an ImportMany property, and composes itself upon creation in the usual way. So m_objHost is populated automagically and the controller has access to all the things the host application provides, like logging and information about the user and what they're currently working on and all that.
My question has to do with my models, and any DAL or utility classes that I have in a plugin. These classes usually have need of information from the IWebHost object. However, the host doesn't need to know about these classes, so they are not included in composition. Since they are not composed, if they want an IWebHost reference they each have to compose themselves upon instantiation, like this:
Public Class MyModel
<Import()>
Private m_objHost As IWebHost
<Import()>
Private m_objLog As ILog
Public Sub New()
Compose()
End Sub
...
Private Sub Compose()
Try
Dim objCatalog As New AggregateCatalog
objCatalog.Catalogs.Add(New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory & "bin"))
Dim container As New CompositionContainer(objCatalog)
container.ComposeParts(Me)
Catch ex As Exception
If m_objLog IsNot Nothing Then
m_objLog.writeError(ex)
End If
End Try
End Sub
End Class
So my main question can be broken into two parts:
Is there any noticeable performance problem with having, say, 20 or so classes that perform composition whenever they are instantiated? I currently only have a few, and if there is a hit it's not noticeable. In other words, do I actually need to change this strategy? It violates DRY because I have a Compose method in every class, but I can learn to live with it.
Is there a better way? How can I handle a single composition in the main application that takes care of populating all of the classes in the plugins, including those not imported in the class performing the main composition?
I've considered the following:
Having all models and utility classes and whatever implement a marker interface, export them all using that interface as a contract, and importing them in the host class, even though the host class doesn't need them. I think this is an even cruddier design than what I have, and I don't want to do it. I'm willing to listen to arguments in favor of this, though.
Having a class in each plugin that needs it that implements IWebHost that acts as a wrapper for the class exported by the main app. I'd still have to do composition in each plugin, but at least it would only be once per plugin. This one seems okay to me.
Thanks in advance for any help you can give, and for reading this whole novel of a question.
I wound up adding a class like the one below to the plugins that need it. I have a project template for plugins, so I'll probably just add this class to that template.
Any class that needs something from the host can access it by calling PluginUtility.Host.
Public Class PluginUtility
<Import()>
Private m_objHost As IWebHost
Private Shared m_objInstance As PluginUtility
Private Sub New()
Compose()
End Sub
Public Shared ReadOnly Property Host As IWebHost
Get
If m_objInstance Is Nothing Then
m_objInstance = New PluginUtility
End If
Return m_objInstance.m_objHost
End Get
End Property
Private Sub Compose()
Try
Dim objCatalog As New AggregateCatalog
objCatalog.Catalogs.Add(New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory & "bin"))
Dim container As New CompositionContainer(objCatalog)
container.ComposeParts(Me)
Catch ex As Exception
Console.Write("Could not compose to get a reference to the host")
End Try
End Sub
End Class
I'm curious of all of the various ways people are building their ViewModels and why they choose that method.
I can think of several ways here:
-1. Injected repository - the controller loads the model and maps to the ViewModel. Here the ViewModel constructor could take various collections to interally set for ex. in a select list such as:
public CustomerController(ISomeRepository repository)
{
_repository = repository;
}
public ActionResult Create()
{
CustomerCreateViewModel model = new CustomerCreateViewModel(_repository.GetShipTypes,
_repository.GetStates);
..
..
}
-2. ViewModelBuilder - Either injected or instantiated in the controller with an instance of the injected repository. Called via something like
>var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
or,
var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
-3. Directly in controller (no code required - its messy)
-4. Some other service (injected or not) that returns domain model which the controller then maps or a ViewModel (anyone doing this to return a view model that isn't specifically named/noted as a ViewModel builder class?)
public JobCreateViewModel BuildJobCreateViewModel(int parentId)
{
JobCreateViewModel model = new JobCreateViewModel();
model.JobStatus = _unitOfWork.JobRepository.GetJobStatuses();
model.States=_unitOfWork.StateRepository.GetAll();
return model;
}
Now on the return trip - regarding validating your view models - are you inheriting from a base ViewModel class for standard validations, or copying your validations (ex. data annotation attributes) between all of your ViewModels, or simply relying on server side validation so it can all be validated againt your domain object?
Any others? Anything better? Why?
EDIT
Based on a link below, I did find a nice article from Jimmy Bogard on the architecture of ViewModels. While it doesn't address the question above directly, it's a great reference for anyone coming here for ViewModel information.
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
I inject a service into the controller, not a repository, and then use AutoMapper to convert it into a view model. The benefit of the service layer in this case is that it could aggregate multiple simple operations from one or more repositories into a single operation exposing a domain model. Example:
private readonly ICustomerService _service;
public CustomerController(ICustomerService service)
{
_service = service;
}
[AutoMap(typeof(Customer), typeof(CustomerViewModel))]
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
return View(customer);
}
in this example AutoMap is a custom action filter that I can write which executes after the controller action, inspects the returned object and uses defined AutoMapper mappings to map it to the specified destination type. So the view gets the corresponding CustomerViewModel as model type. Would have been equivalent to:
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
CustomerViewModel vm = Mapper.Map<Customer, CustomerViewModel>(customer);
return View(vm);
}
it's just that it is too much plumbing and repetitive code that could be centralized.
I would also recommend you watching the putting your controllers on a diet video from Jimmy Bogard.
I just finished a project where we did a variation on #4. We had a service class injected into the controller. The service class held dependencies on the repository and a model builder class (we called it model factory).
The controller called into the service class, which handled business validation logic, and then fetched view models from the appropriate factory. The models themselves relied on data annotations for input validation.
It worked really well for our team. There was enough separation of concerns to allow the devs to do their work without affecting one another, but it was manageable enough to understand what was going on.
It's the first time we tried it and we'll be sticking with it. I'm interested to see how others respond.
Our method is to inject the repository in to the controller and map it to the ViewModel using Automapper http://automapper.org/. Our ViewModels contain data annotation attributes to allow the validation to occur on the client.
We call methods on the repository which return Domain objects (Entity Framework). The domain objects are mapped to the ViewModel. We tend to use the same ViewModel for edits and adds so the data annotations are needed once. In its simplest form it looks like the following code:
public ActionResult List(int custId, int projId)
{
var users = _userRepository.GetByCustomerId(custId);
var userList = Mapper.Map<IEnumerable<CMUser>, IEnumerable<UserListViewModel>>(users);
return View(userList);
}
I use a service layer that hides the domain model from the controller returning ViewModels from the service methods. This allows me to make changes to the domain model without impacting the client.
I am still having a hard time wrapping my head around this. I want to separate my layers (dlls) like so:
1) MyProject.Web.dll - MVC Web App (Controllers, Models (Edit/View), Views)
2) MyProject.Services.dll - Service Layer (Business Logic)
3) MyProject.Repositories.dll - Repositories
4) MyProject.Domain.dll - POCO Classes
5) MyProject.Data.dll - EF4
Workflow:
1) Controllers call Services to get objects to populate View/Edit Models.
2) Services call Repositories to get/persist objects.
3) Repositories call EF to get/persist objects to and from SQL Server.
My Repositories return IQueryable(Of T) and inside them they utilize ObjectSet(Of T).
So as I see this, the layers depend on exactly the next layer down and the lib that contains the POCO classes?
A few concerns:
1) Now for my Repositories to work correctly with EF, they will depend on System.Data.Objects, now I have a tight coupling with EF in my repository layer, is that bad?
2) I am using the UnitOfWork pattern. Where should that live? It has a Property Context As ObjectContext, so that is tightly coupled to EF as well. Bad?
3) How can i use DI to make this easier?
I want this to be a loosely coupled as possible for testing. Any suggestions?
---------- Edit ----------
Please let me know if I am on the right track here. Also, so the Service gets injected with an IRepository(Of Category) right, how does it know the difference between that and the concrete class of EFRepository(Of T)? Same with the UnitOfWork and the Service?
Once someone helps me figure this out to where I understand it, I know it will have seemed trivial, but man I am having a heck of a time wrapping my head around this!!
Controller
Public Class CategoryController
Private _Service As Domain.Interfaces.IService
Public Sub New(ByVal Service As Domain.Interfaces.IService)
_Service = Service
End Sub
Function ListCategories() As ActionResult
Dim Model As New CategoryViewModel
Using UOW As New Repositories.EFUnitOfWork
Mapper.Map(Of Category, CategoryViewModel)(_Service.GetCategories)
End Using
Return View(Model)
End Function
End Class
Service
Public Class CategoryService
Private Repository As Domain.Interfaces.IRepository(Of Domain.Category)
Private UnitOfWork As Domain.Interfaces.IUnitOfWork
Public Sub New(ByVal UnitOfWork As Domain.Interfaces.IUnitOfWork, ByVal Repository As Domain.Interfaces.IRepository(Of Domain.Category))
UnitOfWork = UnitOfWork
Repository = Repository
End Sub
Public Function GetCategories() As IEnumerable(Of Domain.Category)
Return Repository.GetAll()
End Function
End Class
Repository and UnitOfWork
Public MustInherit Class RepositoryBase(Of T As Class)
Implements Domain.Interfaces.IRepository(Of T)
End Class
Public Class EFRepository(Of T As Class)
Inherits RepositoryBase(Of T)
End Class
Public Class EFUnitOfWork
Implements Domain.Interfaces.IUnitOfWork
Public Property Context As ObjectContext
Public Sub Commit() Implements Domain.Interfaces.IUnitOfWork.Commit
End Sub
End Class
Original Answer
No. However, to avoid coupling the Services to this, have an ISomethingRepository interface in your domain layer. This will be resolved by your IoC container.
The Unit of Work patterns should be implemented with your Repositories. Use the same solution to decoupling this as I suggested with decoupling your repositories from your services. Create an IUnitOfWork or IUnitOfWork<TContext> in your domain layer, and put the implementation in your Repository layer. I don't see any reason that your repository implementation needs to be separate from your Data layer, if all the Repositories do is persist data to the ObjectContext in data layer. The Repository interface is domain logic, but the implementation is a data concern
You can use DI to inject your services into the controllers and your repositories into your services. With DI, your service will have a dependency on the repository interface ISomethingRepository, and will receive the implementation of the EFSomethingRepository without being coupled to the data/repository assembly. Basically, your IControllerFactory implementation will get the IoC container to provide all the constructor dependencies for the Controller. This will require that the IoC container also provides all the controllers' constructor dependencies (service) their constructor dependencies (repositories) as well. All of your assemblies will have a dependency on your domain layer, (which has the repository and service interfaces), but will not have dependencies on each other, because they are dependent on the interface and not the implementation. You will either need a separate assembly for the Dependency Resolution or you will need to include that code in your Web project. ( I would recommend a separate assembly). The only assembly with a dependency on the Dependency Resolution assembly will be the UI assembly, although even this is not completely necessary if you use an IHttpModule implementation to register your dependencies at the Application_Start event (the project will still need a copy of the dll in your bin folder, but a project reference is not necessary). There are plenty of suitable open source IoC containers. The best one depends a lot on what you choose. I personally like StructureMap. Both it, and Ninject are reliable and well documented DI frameworks.
Response to Sam Striano's Edits
It's been years since I've coded in VB so my syntax may be off.
Public Class CategoryController
Private _Service As Domain.Interfaces.IService
'This is good.
Public Sub New(ByVal Service As Domain.Interfaces.IService)
_Service = Service
End Sub
Function ListCategories() As ActionResult
Dim Model As New CategoryViewModel
Using UOW As New Repositories.EFUnitOfWork
This doesn't need to be in the controller. Move it into the Repository and have it surround the actual transaction. Also, you don't want your controller to have a dependency on the data layer.
Mapper.Map(Of Category, CategoryViewModel)(_Service.GetCategories)
Is this a call to AutoMapper? Not related to your original question, but, you should relocate the mapping functionality to an ActionFilter so your return is just Return View(_Service.GetCategories)
End Using
Return View(Model)
End Function
The Service class had no problems.
The Repository and Unit of Work look mostly incomplete. Your Repository should new up the ObjectContext and inject it into the Unit of Work, then execute all transactions in the scope of the Unit of Work (similar to what you did in the controller). The problem with having it in the Controller is it's possible that a single Service call could be scoped to multiple units of work. Here is a good article on how to implement Unit of Work. http://martinfowler.com/eaaCatalog/unitOfWork.html. Martin Fowler's books and website are great sources of information on these types of topics.
To answer your concerns in order
1) Not necessarily bad, kind of depends on how likely you are to stick with EF. There are several things you could do to reduce this. One relatively low cost (assuming you have some Inversion of Control setup, if not skip to 3) is to only reference interfaces of your repositories from your services.
2) Same again, I think you could spend a lot of time not making your application not coupled to EF but you have to ask yourself if this change of direction would not make for other changes as well. Again, a layer of indirection could be brought in through interfacing and easily swap out one repository implementation with another later.
3) Inversion of Control should again allow all the testing you'd want. Thus no need for many direct references at all and to test any layer in isolation.
UPDATE for requested sample.
public class QuestionService : IQuestionService
{
private readonly IQuestionRepository _questionRepository;
public QuestionService(IQuestionRepository questionRepository){
_questionRepository = questionRepository
}
}
Thus your service only knows of an interface which can be mocked or faked within your unit tests. It is all pretty standard IoC stuff. There is lots of good reference out there on this, if a lot of this is new to you then I'd recommend some a book to give you the full story.
I would suggest using MEF. It gives you the dependency injection framework you want but it isn't full-fledged; it's excellent for unit test. Here are a few answers to a related question: Simplifying Testing through design considerations while utilizing dependency injection
Full code exmple can be found here with MEF and Repository Pattern (also uses EFCodeFirst).
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