Entity Framework References, Multi Layer App - asp.net-mvc

I have set up my MVC app with seperate Class Libraries for my Domain (POCOs) and Repositories. Now my DbConxet is currently in the domain layer and i wanted to add the following:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
but it couldnt find DbModelBuilder. Now I checked my references and noticed it was referencing EFCodeFirst0.8/lib/EntityFramework.dll When I changed this to EntityFramework4.2.0.0/lib/EntityFramework.dll DbModelBuilder was available but I get errors because the other projects in my solution (MVC and Repo) are referencing the original dll. So I update them but then the MVC layer has a problem in App_Start/SQLCEEntityFramework.cs
What have I done wrong?! Should I have the OnModelCreating in another part of my app and reset all the references to the original EFCodeFirst0.8/lib/EntityFramework.dll? Or fix up the errors in App_Start/SQLCEEntityFramework.cs?
Thanks all,
James

You are doing it wrong :)
There is really no point in POCO, repository pattern, and all that stuff intended for persistance ignorance, when you have entity framework referenced everywhere and your domain is tied with it.
Your domain should be pure class library (with things like componentmodel, dataannotations of course) without referencing EF.
Then you should have "contract" (that is interface, in another class library) between your MVC app and "all the possible repositories" - also EF agnostic.
And finally you have "one particular implementation" of that contract - your EF repository. That should be the only project referencing EF library.
The point is, that if tommorow your boss comes and says "ok, we switching to nhibernate", you sould replay "no problem, i just write another repository implementing this interface with it and change 1 line in IoC container configuration". And as a bonus, you can update your EF reference in 1 place only :)

Related

.NET MVC3 Project Structure

I have looked around but cannot find anything that answered this particular question related to file/project structure.
I have an MVC3 site using entity framework. It follows a basic generic repository pattern using StructureMap to handle dependency resolution.
My question is, how do I lay the projects out? taking in mind I may want to expose the database to another application down the track.
Currently I have:
mySite.Web -- MVC Project also has all the dependency resolution
mySite.Web.Data -- EntityFramwork CodeFirst, Repository pattern
mySite.Web.Tests -- Tests... :-)
Should I be moving my EntityFramwork models to there own project? if so where would things like my EntityContextFactory go?
Thanks
I have the same problem - How to setup a new mvc project?
My research and help for other user is: A good structure approach is the Domain Driven Design for MVC Architectures.
good blog post for DDD
my new project structure will look something like this:
Presentation.Web (Controller, Views, ModelViews..)
Presentation.Web.Utils (Helper and Extensions..)
Presentation.Web.Tests (Moq..)
BusinessDomain.Services (Business Service for DI )
BusinessDomain.Models (EF Models..)
BusinessDomain.Tests (Moq..)
CrossCutting.Common (Const, Resources, Exception Msg...)
Infrastructure.Configuration (IoC Bootstrapper, ApplicationConfiguration,ContainerExtensions..)
Infrastructure.DataSource (DbContext, Repositorys..)
Infrastructure.Tests (Moq..)
I would create a new project called mySite.Domain and possibly create a entities folder in that project and place them in there.
I'd only store entities in the Domain and keep all repositories, your dbcontext and entity contextfactory in your Data project.
Here are some sample projects you could have a look at (credit to authors):
http://myfinance.codeplex.com/
https://github.com/darind/samplemvc
This is largely subjective though.
No this structure is good.you may move pattern repository to mySite.Web or create another class library project for it but it is not necessary.

How to properly decouple Structure Map dependency resolver from ASP.NET MVC web project?

While developing web project using ASP.NET MVC, I came up against a coupling problem.
When I build custom controller factory (or dependency resolver if using MVC 3), I need this factory to know somehow where to get dependencies from. Here's my code:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory class is responsible for injecting dependencies into a controller. As I said, it needs to know where to find these dependencies (I mean concrete classes, like services and repositories implementations).
I have a separate class library called MySite.Data, where all the implementation details live. Contracts, like IAccountRepository, live in library MySite.Contracts. Now, if I reference this MySite.Data library directly from MVC project, there will be a dependency between my site and implementation of its data retrieval. The question is how can I remove it? What are best practices in this situation?
I'm sure it does have a bunch of workarounds, just I haven't found any yet.
Well, as I see it, you can't do exactly that. Your MVC project really really needs to know about concrete classes it is going to use.
You will anyway have to provide those container registrations somewhere and you'll get the dependency on the project/assembly where that type is defined. Shortly, you have to reference MySite.Data from MVC project. Like that:
MySite.Data knows nothing about MVC project
MVC project knows the concrete repositories types to provide correct container registrations.
You can make life simpler with StructureMap Registry objects but you need to include those Registries somewhere as well. Typically those are in the main project or some "StructureMap-adapter" project but you'd need to make reference anyway.
I'd advise that you:
Use MVC3 and drop your custom IControllerFactory if you only use it for DI into your Controllers.
Use StructureMap Registry objects to provide each and every IoC registration ever needed.
Use StructureMap Assembly scanning capabilities to provide components discovery.
Use something much more common as a DependencyResolver, i.e. not a StructureMapControllerFactory but a CommonServiceLocator with StructureMap adapter instead.
Try to abstract from StructureMap itself inside your main app.
And, of course, don't be afraid of making references inside the main project - they have nothing about coupling. It doesn't decrease maintainability. But the wrong architecture does, so be worried about that, not simple reference.

MVC3 EF4 POCO Repository/UnitOfWork Connection Error

I implemented the T4 Repository/ Unit of Work templates by Gil Fink for use in a project I am working on, my first full scale project using MVC. I am, however, getting an error I wasn't getting before, and I can't track it down. I don't know if it's something with the templates, or just a setting somewhere I have set wrong, but I am at a lose right now. I was hoping someone would be able to shed some light on the situation.
Here's my framework setup:
MVC 3 Beta
SQL Server 2008 R2
Ninject v2.1.0.76
EF4 POCO
3 projects in the solution: Data, Entities and the MVC app.
I am doing a DB first design, and using EF to create the POCO classes, via Microsoft's ADO.NET POCO Entity Generator. I then use the T4 tool to create the repository and unit of work patterns. With that setup, and all the classes and repositories generated, I implement it into the MVC app using Ninject for DI. I am using the MVC 2 method using a Controller Factory at this point, with plans to later change it to the IDependencyResolver method.
When I use a hard-coded Mock repository, the application works as it should, however when I change it to use the IRepository binding, I get the following error:
"The supplied connection is not valid because it contains insufficient mapping or metadata information.
Parameter name: connection"
This indicates to me that the connection string for EF to connection to the DB is incorrect, however it is the default string generated by the ADO.NET Entity Data Model template. Perhaps it is also something with the .edmx settings.
Here is my connection string (using the handy Nerd Dinner database layout)
<add name="NerdDinnerEntities"
connectionString="metadata=
res://*/Model1.csdl|
res://*/Model1.ssdl|
res://*/Model1.msl;
provider=System.Data.SqlClient;
provider connection string="Data Source=Wayne;Initial Catalog=NerdDinner;Integrated Security=True;Pooling=False;MultipleActiveResultSets=True""
providerName="System.Data.EntityClient" />
Anyone with any thoughts/ hints, etc, I would be extremely appreciative.
Edit: here's the link for the T4 template I'm using:
Repository and Unit of Work T4 Template for Entity Framework
Edit2:
The error is something to do with home I'm using DI with Unit Of Work. when I remove DI, and manually have the dependencies in the controllers, it works. When I try to implement DI, it breaks.
res://*/Model1.csdl|
That * is a wildcard that says to EF "scan all the assemblies for the resource". Chances are this scan isn't finding the assembly for whatever reason.
Change * to your assembly name:
res://My.Assembly.Name/Model1.csdl|
If you are using NuGet to install your Ninject dependency, it likes to set up your DI bindings in NinjectWebCommon.cs. If loading your DI bindings requires an Entity Framework context to be instantiated, this happens too early in the application lifecycle and the application can't interpret the connection string properly.
If you think this is may be what's happening to you, see my answer here for more information.

MVC 2 and Entity Framework - Should I put Entity classed in separate layer?

I'm trying to find some information on preferred solution setup when using MVC 2 and Entity Framework, and it would seem most intuitive to me to set this web app up in 3 layers:
MyProject.Web (MVC project for presentation)
MyProject.Data (Data gateway layer using Entity Framework to speak to the DB)
MyProject.Tests (Test project as created when setting up a new MVC project)
This seems to be contrary to the examples I'm finding, and the documentation (eg, the NerdDinner example) which see the MVC project as mediating directly with the database. The NerdDinner example puts the data access in a repository class mixed in with the MVC models.
I've tried going with the way which seems best to me, and have created my "ADO.NET Entity Data Model" item in my separate Data project, but this gives me an error when I try to use MVC to list the items in it:
"Unable to load the specified metadata resource."
unless I have a copy of the Entity Data model in my MVC project as well.
Before I go too far down the road of looking into this error, I want to find out if I'm just fighting against the framework for purism when I could just be disciplined with only using data access in my repository.
so:
- Is it even possible or recommended to put my Entity Framework def in this other project?
- Will I be sacrificing certain other MVC features by separating it out in this way? (eg, validation?)
- If I'm heading in the right direction and others agree, are there any other examples or docs out there someone could point me at?
Yes, I think it's a good idea to put your entities in a separate assembly.
One way to fix the "Unable to load the specified metadata resource" error is to specify the assembly in the connection string explicitly:
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/AssemblyName.bin.Namespace.MyEntities.csdl|res://*/AssemblyName.bin.Namespace.MyEntities.ssdl|res://*/AssemblyName.bin.Namespace.MyEntities.msl;provider=System.Data.SqlClient;provider connection string="Data Source=SERVER_NAME;Initial Catalog=DBName;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
</connectionStrings>
Note, especially, the AssemblyName.bin.Namespace.MyEntities. This is the assembly-qualified resource name (assuming the assembly is called "AssemblyName.dll". You may need to use Reflector to figure it out the first time you do this.
This answer might also be helpful.
It is certainly possible to put your Entity Framework definition in another project. Personally, I keep it in another project if the data layer will need to be shared by multiple interfaces (MVC, WCF, WPF).
Take a look at these two MSDN articles on building and using an EntityConnection.
Build an EntityConnection
Use EntityConnection with an Object Context

MetadataTypeAttribute not available in DNX Core 5.0

I want to use the MetaDatatType attribute in a MVC6 project and it does't seem to be available yet. I am using 7.0.0-rc1-final so it should the latest.
Does anyone know if it is in another assembly?
I get the error, The type or namespace name MetadataType could not be found.
After some googling it seems like this attribute is not available in MVC 6. You can use it in the full DNX, but it is unavailable in DNX Core.
Of course, you can decorate your code with
#if DNXCORE50
...
#endif
so that you get no errors when compiling for the full DNX, but it looks like the attribute does not do what it is expected. For example, DisplayName(Name = "...") does not work (I didn't check the other options like Required etc.).
IMHO, Fluent MetadataProvider may be a solution to this, only I do not know if it was ported to vNext. I am going to contact the author(s) and if they are not able to port it soon I'll fork it and will make an attempt to port it myself.
EDIT: ModelMetadataType replaces MetadataType. You must reference Microsoft.AspNet.Mvc.Core. I am not quite sure but maybe you'd need Microsoft.AspNet.Mvc.DataAnnotations too.
Anyway, my thoughts about Fluent Data Annotations (Fluent MetadataProvider) are still valid. You may also need to read an interesting article about this: Why You Don't Need ModelMetadata.Attributes by Brad Wilson.
I've ran into same problem. I'm experienced with Asp.NET MVC 5 but I feel a newbie with Asp.Net Core 1.0 (Full Framework 4.6.1). I have a Class Library for models (Framework 4.6.1) using telerik dataaccess core. Using MetadataTypeAttribute for decorating a model class by using a buddy class was almost a headache due to it not worked at all!. Trying almost anything was frustrating. So what was the solution for me?
I had to use ModelMetadataTypeAttribute instead of MetadataTypeAttribute from Microsoft.AspNetCore.Mvc.Core assembly. Decorating a metadata class (buddy class) follows same methodology of using Display(...), DisplayName(...), same for validators. No matter if the buddy class (Metadata Class) is located external from or internal to the model class.
However using MetadataTypeAttribute directly with the model class instead of a buddy class, works perfectly!
The only explanation I could give about this divergence is related with the new emerging Microsoft Asp.Net core technology, relocation of DLL process and functionalities.
PD: It's not required Microsoft.AspNetCore.Mvc.DataAnnotations

Resources