I am working on an asp.net core mvc 2.0 web application.
This application works with an sql server database and entity framework core.
I want to create a console project for doing some batch stuff at night. This project should access the same database than the web project.
So i decided to create a third common project (library) which will contains models classes, db context and migrations.
The 2 project will reference this common project.
When i try to run "dotnet ef" commands in the terminal, in the common project subfolder, i get an error saying me this project should be startup project. But this is a shared library ...
EF Core differs from EF in that the context is designed to be instantiated via a dependency injection container. In other words, it relies on a DbContextOptions instance being injected that tells it among other things what type of database connection to use and how to connect. Since this injection only occurs inside projects that actually run (i.e. not a class library), the EF command-line tools only work by default with "startup projects", i.e. projects that can actually be started.
To enable migrating against a class library, EF Core provides IDesignTimeDbContextFactory. The EF commands will look for an implementation of this interface, and if it exists, use that factory to create the context it needs. As a result, you simply need to create an implementation in your class library.
public class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
{
public MyContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer("[connection string here]");
return new MyContext(optionsBuilder.Options);
}
}
Yes, this means you need to hard-code your connection string, but importantly this is not environment-specific. More appropriately, the only environment you should be migrating in is development, so you don't need it to be environment-specific.
Documentation
Related
I have a web application with n-tier architecture. All the POCO classes are in a class-library project named EntityFramework and the DBContext class named DB. And another project is WebAPI with all the API controllers. I added the following code in my WebAPI controller:
using EntityFramework;
namespace WebAPI
{
private DB db = new DB();
}
Although I have added the reference of EntityFramework in WebAPI but still the line 'using EntityFramework;' has the red wavy underline and DB object cannot be created.
First of all read what the error message is saying and put it in your Post.
There could be a number of issues that cause that. A couple guesses from me:
You now have 2 dlls called EntityFramework and the code does not know which one you want to reference, hence the error.
the version of the dll does not match where you reference it. So, check both projects and make sure they both target the same framework version.
Do not call your DTO library EntityFramework, chances are you will get issues with the actual EntityFramework dll. Call it DTOs or Models, or anything else.
I am just getting my feet wet using Entity Framework 4.3 and Migrations for a SQLServerCompact 4.0 database, so I am using the simplest possible methods to get things started. Following the advice in this blog I added the initialization statements below to the Main method of a console application. This all works very well.
Database.DefaultConnectionFactory = New SqlCeConnectionFactory("System.Data.SqlServerCe.4.0")
Database.SetInitializer(Of MySQLCompactDbContext)(New MySQLCompactDBInitializer)
But in production the code addressing the database will be located in a class library that will be accessed through COM-interop from a Visual Basic 6 application. So there is no natural entry point for the code where to put the static methods mentioned above.
Where can I put them?
Please point out the alternative way using the config file if necessary.
(I had a hard time titling the question so feel free to suggest edits)
Here's the situation: we have just started building a system which is comprised of two integrated MVC 3 web applications running on Azure with a shared AzureSQL database. There are many reasons for running two apps instead of one and I'd rather not get into that...
Originally, database was created code-first from the MVC application "A". 75% of entities from all created will be relevant to application "B" plus application "B" will need a few entities specific to it.
Currently, the entities-defining classes have been extracted into a class library so within the application "A" solution to allow for reuse in application "B". But I am still unsure how to go about adding entities required for application "B"...
The question is: what is the best way to manage the database development/management in this situation? Specifically, where should the definition of entities be? Should we just have a separate db project defining the database and work db-first? (with this option being my preferred at this stage).
Since both of the devs (me and the other dev) working on this are new to MVC and EF, any advice would be much appreciated.
Without seeing what you have its not entirely mapping here in my brain - but I think I may have an idea on this.
Can you create an additional projects containing your models (data access layer) that has your entity framework edmx (or code first) and poco templates installed. This project will be shared by both applications - ie both projects get this assembly and both have the ef connect string in their web.configs.
Another approach is to put all code first into a single project (whatever.domain, whatever.models) etc. Your mapping code then goes into your DataAccess project
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();
modelBuilder.Configurations.Add(new CustomerMap());
...
}
You now have shared poco classes and a single data access layer.
Some treat their poco classes as their domain objects (theres no problem with this) and their business logic goes in the poco classes. This is fine as long as your poco objects themselves remain persistent ignorant and ideally you don't want to reference implementation specific components in your poco classes. For a good writeup here see:
POCO - if POCO means pure .net class with only properties, where i can write validations in MVC
Personally I like db first and then reverse engineer it using the EF power tools to have a code first model as if you ever want to integration test it, you can simply create the db for your integration tests and remove it when done.
I've been looking into Ioc containers and AOP recently, and I'm pretty amazed by the concepts. I'm struggling however to decide how and where to implement the container.
The articles below suggest implementing the container in the 'application entry point':
Best Practices for IOC Container
IOC across visual studio projects?
Not understanding where to create IoC Containers in system architecture
Now - my thought-experiment application will consist of multiple visual studio projects ( one for data access, winforms application ). And let's say I want to use AOP for logging with Log4net, and so I setup log4net in the Ioc container.
So WinForms application in entry point, that's where Ioc container should go.
Here's the question: if I want to log stuff in my data access project/layer, should I add a
reference to my winforms application, get the ioc container from there, get the log4net instance out of it and use it for logging?
That would mean my data-layer depends on winforms application, that can't be right. How about I put the container is something like a 'Common' project within the solution. That way, all related projects (Data access/winformsa etc.) can access the container.
What is the right way to go here?
Your application's Composition Root would be the Windows Forms project. This is the only project which should have a reference to a DI Container.
In all other projects, dependencies should be injected via Constructor Injection. All decent DI Containers understand this pattern and use it to Auto-wire dependencies from the Composition Root.
I've abstracted my container into a separate assembly that all other assemblies / projects depending on its services reference. The container project has just a single class and - more or less - a single method:
public class MySpecialContainer
{
public T Resolve<T>() { // ... Get stuff from the IoC container }
}
The container build would either occur in MySpecialContainer's ctor or just add another method like Initialize() or some such.
The only problem is this approach broke down for me when I used Autofac and had both a Windows Service and ASP.Net project needing the container. Each had its specific requirement for scoped-lifetime services: Windows Service - PerLifetimeScope, ASP.Net - PerHttpRequest. I guess I could've passed in an argument into MySpecialContainer that denoted which scenario to configure for but I decided just to take on an Autofac dependency directly.
The good news is, if you stick to ctor injection, then you can very easily swap out various container implementations - Autofec, Ninject, StructureMap, etc.
I'm new to Unity, but this question is more generic to IoC, and I’m pretty new to implementing IoC as a whole. I have VS2010 solution with this project structure (simplified slightly):
Business Objects – Folder
DomainModel (Class Lib prj.) – Entity Framework 2 POCO entities
Data Layer – Folder
DataAccess (Class Lib prj.) – EF2 EDMX
Repository (Class Lib prj.) – IRepository interface & repository concrete implementations
Presentation Layer – folder
WebUI – MVC Project
Service Layer
Service (Class Lib prj.) – IService interface and service (façade pattern) concrete implementations
All project reference the DomainModel project.
Repository references the DataAccess project.
Service Layer references the Repository project.
WebUI references the Service project & the Unity assemblies.
I have Unity configured to inject all my service types correctly in the WebUI (global.asax via a custom UnityControllerFactory.cs). But how do I configure Unity in the service layer to inject the repository objects?
I DON’T want to reference the Repository project from the WebUI to ensure during development no one shortcuts and bypass the Service layer.
Couple Ideas I have (not sure if it will solve it):
Move the IRepository Interfaces into the DomainModel and add the Unity.RegisterType<> calls for the IRepository
Set up Unity configuration in the Web.config
Any direction would be greatly appreciated, specifically to how to configure Unity for the service layer / Repository, but also in general about the project.
Add a bootstrapper of some sort in the Service project. Then reference the bootstrapper in the WebUI.
One way to do this would be to write a small Unity extension. Something like this:
public class ServiceLayerBootstrap : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IRepository, WhateverRepositoryImplementation>();
// etc.
}
}
Then, in the web project where you create the container and initialize it, do this:
var container = new UnityContainer()
.AddNewExtension<ServiceLayerBootstrap>();