Multiple string connections in EF DbContext - asp.net-mvc-4

I’m developing a MVC Website based in codeplex EFMVC solution, and I’m using Entity Framework and Repository, Unit of Work and Command Patterns. My website needs to be a SaaS solution (software as a service) multiple database.
In my legacy Asp.Net WebForms I have a XML file that holds all the different string connections and I’m trying to use the same strategy. So in my LoginController I create a command that has company (to identify in which database will be connected) username and password. At Validate() method in Domain project, I’m reading the XML to get the correct string connection based on company field. My problem is how can I set the DatabaseFactory or DbContext to use this selected connection string? It should be injected at the constructor? Any suggestion for doing this in the correct way, without “breaks the rules”?
Note that I’m using AutoFac for Dependency Injection.
Thanks for your attention.
Best Wishes,
Luiz Fernando Vall Dionizio

You can use the ResolveNamed feature of Autofaq to get different registration for the same Interface
For instance:
builder.Register<IDataContext>(x => new DataContext(connectionStringOne))
.Named<IDataContext>("CS1");
builder.Register<IDataContext>(x => new DataContext(connectionStringTwo))
.Named<IDataContext>("CS2");
and to resolve it
var context = ContainerAccessor.Container().ResolveNamed<IDataContext>("CS1");
Another way is to override the DataContext ctor and read the configuration from an shared location for that request.

Related

How generate a workflow in runtime with elsa workflow

With Elsa workflow designer possible to define a workflow and publish it, also can make a workflow programmatically by implementing the IWorkflow interface.
I need to make programmatically workflow at runtime, save it on the database and run it sometimes.
in the asp.net core project controller, I resolve IWorkflowBuilder as a dependency and make a workflow with WorkflowBuilder and return a WorkFlowblueprint object, but I don't know how I can store it and how to run it?
I also have Elsa dashboard on my project and I use EntityFramework Persistence for it.
Is there a way to convert a WorkflowBluePrint to WorkFlowDefination or generate WorkflowDefination from scratch programmatically?
Does everyone have any idea?
Although it might theoretically be possible to store an IWorkflow implementation in the database, there are some caveats that make this tricky to say the least. Here is why:
A workflow definition created by the designer consists purely of a list of activities and connections between them. Because of that, everything is easily serialized into JSON and stored in the database.
However, when you write a C# class, you can do more fancy things, such as configuring activities using C# lambda expressions and implement "inline" activity code. When you try to serialize this to JSON, these C# expressions will be serialized using just their type names.
Although there might be ways to somehow store a programmatic workflow into the database, perhaps even by storing a compiled assembly in the DB, I don't think it's worth the trouble because there are better ways.
You said that you need a programmatic workflow that you only run sometimes.
To achieve that, you do not need to store a workflow in the database.
The way Elsa works is that all workflow sources are converted into a thing called a Workflow Blueprint.
A workflow blueprint is what represents an executable workflow where all the necessary details are dehydrated that the workflow invoker can use.
There are different "sources" to establish these workflow blueprints by means of classes that implement IWorkflowProvider, of which there are three:
Programmatic Workflow Provider
Database Workflow Provider
Blob Storage Workflow Provider
The programmatic provider is what turns IWorkflow implementations into workflow blueprints, while the database provider turns workflow definitions into blueprints. The blob storage provider is similar, except it turns JSON files into blueprints.
The bottom line is that the origin of a workflow blueprint doesn't matter for the workflow engine.
All workflow blueprints are accessed through a service called the workflow registry, which you can use to load & execute a given workflow.
For example, if you have a programmatic workflow called MyWorkflow, you can execute it whenever you want like this:
public class MyWorkflow : IWorkflow
{
public void Build(IWorkflowBuilder builder)
{
builder.WriteLine("Hello World!");
}
}
[ApiController]
[Route("my-workflow")]
public class MyWorkflowController : Controller
{
private readonly IWorkflowRegistry _workflowRegistry;
private readonly IStartsWorkflow _workflowStarter;
public MyWorkflowController(IWorkflowRegistry workflowRegistry, IStartsWorkflow workflowStarter)
{
_workflowRegistry = workflowRegistry;
_workflowStarter = workflowStarter;
}
[HttpGet("run")]
public async Task<IActionResult> RunMyWorkflow(CancellationToken cancellationToken)
{
// 1. Get my workflow blueprint.
var myWorkflowBlueprint = (await _workflowRegistry.GetWorkflowAsync<MyWorkflow>(cancellationToken))!;
// 2. Run the workflow.
await _workflowStarter.StartWorkflowAsync(myWorkflowBlueprint, cancellationToken: cancellationToken);
return Ok();
}
}
Invoking this controller will execute MyWorkflow.
As you can see, there is no need to store the workflow in the database in order to be able to execute it on demand. Even if you did store the workflow in the database, the code would be the same, provided that the name of the workflow remains "MyWorkflow". Under the covers, the GetWorkflowAsync<TWorkflow> is simply an extension method that uses the type name to find the workflow by name. If you wanted to load a workflow by name for which there's no workflow class defined, you would simply use FindByNameAsync, or FindAsync if all you had is a workflow definition ID.

Change the connection string dynamically (per request) on Entity Framework 7 / MVC 6

I have a MVC 6 application on which I need to connect to a different database (i.e. physical file but same schema) depending on who is accessing to it.
That is: each customer of the web application will have it's data isolated in an SQL database (on Azure, with different performances, price levels, etc.) but all those databases will share the same relational schema and of course, the Entity Framework context class.
var cadConexion = #"Server=(localdb)\mssqllocaldb;Database=DBforCustomer1;Trusted_Connection=True;";
services.AddEntityFramework().AddSqlServer().AddDbContext<DAL.ContextoBD>(options => options.UseSqlServer(cadConexion));
The problem is that if I register the service this way I've tied it to a concrete database for a concrete customer, and I don't know if I can change latter when the middleware execution starts (this would be a good point as I can know then who is ringing at the door).
I know I can construct the Database Context passing the connection string as a parameter but this would imply that I should be creating the Database Context at runtime (early in the pipeline) for every request adn I don't know if this could be potentially unefficient or a bad practice. Furthermore I think this way I can't register the Database Context as a service for injecting it on my controllers...
What is the correct approach for this? Anybody has a similar configuration working on production?
Thanks in advance
I would have preferred not to answer my own question, but I feel that I must offer guidance to those with a similar problem, after a long and deep research over internet so I can save them a lot of time testing multi-connection scenarios, wich is quite laborious...
I've finally used a (very recent) feature and APIs of Azure called "Elastic Database Tools" wich, to be concise, is a set of tools from Microsoft aimed to address this concrete problem, specially for SaaS (software as a service) scenarios (as mine is).
Here is a good link to start with:
https://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-scale-get-started/
Good luck with your projects!
First of all, I do not recommend swapping connection strings per request.
But that's not the question. You can do this. You will need to pass your DbContext a new connection string.
.AddDbContext caches the connection string in the dependency injection container, so you cannot use DI to make this scenario work. Instead, you will need to instantiate your DbContext yourself and pass it a new connection string.

Risks of holding an Entity Framework dynamic proxy object in session?

So I have a fairly comprehensive activity-based access control system I built for a web app under MVC 4 using Entity Framework. Well, to be precise the access control doesn't care if it's using EF or not, but the app is.
Anyway, I'm loading the user's permissions on each request right now. I get a reference to my DbContext injected from the IoC container into my ApplicationController, and it overrides OnAuthorization to stuff the user's profile into the HttpContext.Current.Items. Seems to work fairly well, but I can't help but wonder if it's the best way.
My thought was that since the users' permissions don't change often, if ever, the better way to do it would be to load the profile of permissions into the Session instead, and then not have to change them at all until the user logs out and logs back in (pretty common in desktop OS's anyway). But I'm concerned that if I fetch using the DbContext, then the object I get back is a dynamic proxy which holds a reference to the DbContext and I certainly don't want to do that for the whole session.
Thoughts? Is this a good approach, and if so how do I ensure that my DbContext doesn't linger beyond when I really need it?
Invoke .AsNoTracking() on the Set<UserPermission> before you query out. Entities will still be proxied, but will be detached from the DbContext.
var userPermission = dbContext.Set<UserPermission>().AsNoTracking()
.SingleOrDefault(x => x.UserName == User.Identity.Name);
Thoughts? Is this a good approach?
Putting a dynamically proxied entity in session will break as soon as you load balance your code across more than 1 web server. Why? Because of the dynamic proxy class. Server A understands the type DynamicProxies.UserPermission_Guid, because it queried out the entity. However Server B through N do not, and therefore cannot deserialize it from the Session. The other servers will dynamically proxy the entity with a different GUID.
That said, you could DTO your data into a POCO object and put it in session instead. However then you do not need to worry about your entity being attached to the context when you first query it out. AsNoTracking will only make the query perform a bit faster.
// you can still call .AsNoTracking for performance reasons
var userPermissionEntity = dbContext.Set<UserPermission>().AsNoTracking()
.SingleOrDefault(x => x.UserName == User.Identity.Name);
// this can safely be put into session and restored by any server with a
// reference to the DLL where the DTO class is defined.
var userPermissionSession = new UserPermissionInSession
{
UserName = userPermissionEntity.UserName,
// etc.
};
Thoughts? Is this a good approach?
Another problem attached to this approach is when you use the common pattern that create one dbContext per http request. This pattern typically dispose dbContext when the request ends.
protected virtual void Application_EndRequest(object sender, EventArgs e)
But what happen when we try to get navigation property of a proxy entity which reference to a disposed DbContext?
We will get a ObjectDisposedException

MVC4, UnitOfWork + DI, and SimpleAuthentication .. how to decouple?

I'm currently working on an MVC4 project, i make use if Ninject to inject a UnitOfWork into my controllers, and I'm using UnitOfWork + Generic Repository pattern.
I don't like VS2012 MVC4 template because it directly uses database access (db initialization, for example).
My project divides in:
a UI project (the mvc4 application), with Forms Authentication
a Domain project (the db entities, the repositories, the UnitOfWork interface plus two UnifOfWork implementations, one with MOQ and one with EF; they are injected into UI controllers via Ninject).
I looked at this example:
http://kevin-junghans.blogspot.it/2013/03/decoupling-simplemembership-from-your.html
related to this question
SimpleMembership - anyone made it n-tier friendly?
And now I have some question:
How can i inject my UoW here? WebSecurity class is static, there is no contructor, it directly instantiate the UoW to perform activities on db ...
I always have to initialize WebMatrix to directly access DB? This piece of code:
public static void Register()
{
Database.SetInitializer<SecurityContext>(new InitSecurityDb());
SecurityContext context = new SecurityContext();
context.Database.Initialize(true);
if (!WebMatrix.WebData.WebSecurity.Initialized)
WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection("DefaultConnection",
"UserProfile", "UserId", "UserName", autoCreateTables: true);
}
breaks my decoupling with the Domain .. how can i make WebSecurity using my UnitOfWork for example? what is the best practice?
How can i store additional data (for example, EmailAddress and so on) and retrieve it, without performing a Database query everytime i have to access the User profile? Something like the old CustomPrincipal ... Custom principal in ASP.NET MVC
Thank you!
You have a lot of questions here Marco. Let me take a stab at them.
How to inject a UOW
Static classes and dependency injection do not mix well, as pointed out in this QA. When I first went through this exercise of decoupling SimpleMembership the concentration was just on decoupling from the domain, as discussed in the article you referenced. It was just a first step and it can be improved on, including making it easier for dependency injection. I debated whether to make WebSecurity static or not and went with static because that is how the original SimpleMembership is implemented, making it a more seamless transition for user of the SimpleSecurity. SimpleSecurity is an open source project and contributions are welcome. Making it non-static would not be difficult and probably makes sense in the long run. Once it is made non-static we could use a Factory pattern to create the UnitOfWork and inject the appropriate Factory.
Why do I have to Register WebSecurity?
SimpleSecurity is just a wrapper around the WebMatrix WebSecurity classes, which require initialization. The Register method just makes sure that WebMatrix is initialized and initializes our database. I disagree that having this method call in the Globa.asax couples it with the Domain in any way. Having it work with your UnitOfWork should have nothing to do with the Application Domain, or with having to call a Register method at application start-up.
How can I store additional data (ex: email) and retrieve it, without performing a database query every time?
This is actually accomplished quite easy in .NET 4.5 by using ClaimsPrincipal. All principals in .NET 4.5 inherit from ClaimsPrincipal, which allows you to store information in the principal as claims. Claims are basically key value pairs that let you store any type of data on the user. For example in ASP.NET the roles for a user are stored as claims. To add your own claims you need to do something called claims transformation. Then to retrieve the information you can create a custom claims principal. Adding this to SimpleSecurity would be a nice feature.

Simplest way to use NHibernate for the official "ASP.Net MVC 3 Getting Started"-Tutorial

Clarified Updated Question - Start
In the official MVC 3 Getting Started-tutorial it seems to me that all we have to do to get ORM working are two steps.
First adding the simple MovieDBContext-code as described at the end of part 4 ..
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
.. and second in the beginning of part 5, with a simple right-click on the Controllers folder we can auto-generate a MoviesController that implements CRUD()-functionality using Entity Framework by simply telling which Model to use.
Now when using the web-application we can already write and read from the database.
What would be the simplest (or a simple) way to get this done for our Movie-Model with NHibernate instead of using Entity Framework?
Clarified Updated Question - End
Original question (only for additional background-info):
I'm trying to create an ASP.Net MVC 3 application that uses NHibernate and Postgres.
Background Info
Development is done on Windows with Visual Web Developer Express, the production environment will be/should be Linux+Mono.
Steps that have worked so far:
An ASP.Net Dynamic Data Entities Web Application using Npgsql and Postgres as the DB.
Successfully run on Windows development machine.
(Following this tutorial)
An ASP.Net MVC 3 application without using a database/model yet:
Succesfully run on Windows development machine and deployed to Linux production environment using Mono and Nginx. (Only as a proof of concept for myself not as a web app used by the public.)
An ASP.Net MVC 3 application with a model using SQL Server Express as the DB.
Successfully run on my Windows development machine.
(Following the MVC 3 Getting Started-tutorial)
Question
So far I managed to get Postgres to work with a "Dynamic Data Entities Web Application" but with an MVC 3 Web app I'm stuck on where/how to start. For the last mentioned MVC-3-Movie-Webapp I want to switch the DB from SQL Server Express to Postgres using NHibernate and Npgsql (NHibernate since Mono doesn't support Entity Framework).
When you look at the end of part 4 there's the simple MovieDBContext-code
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
and in the beginning of part 5, we autogenerate CRUD-stuff using Entity Framework by simply telling which Model to use.
(MoviesController.cs, Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, and Index.cshtml)
So I have that working with Entity Framework and SQL Server Express, but how would I achieve the same result by using NHibernate? (doesn't have to be with postgres immediately, sticking with SQL-Server as a first step would be fine) (Hopefully with similar simplicity, but getting the result itself would be great)
I found a lot of old stuff and how I would manually map things, but what would be a good-up to date standard way of achieving this with NHibernate for MVC 3?
(The closest thing I found was the source code mentioned in this thread, but it's 64 MB unzipped I got several "Projects not loaded successfully"-errors and the author said he uses MVC 2 so I think it's a little over my head for being a complete NHibernate noob.)
I think showing how this is done could be very useful for others as well, since the original tutorial is very easy to follow and is linked as the official starting point for MVC 3 app-development on http://www.asp.net/mvc ("Your First ASP.NET MVC App").
So I think this would be a great up to date example about how to use NHibernate with MVC 3.
Actually, those automated things haven't helpful enough in real world applications. We have to separate concerns and by using DataContext in UI Layer is not a good practice because that dependency will cause problems like lack of test-ability, violation of best practices. I think you need to have following things of your project
Separation of Concern (Layered Architecture - UI Layer, Servie Layer, Domain Layer, Infrastructure Layer)
Generic Repository and Unit of Work wrapping (Database functionalities, ORM - EF, NHibernate, etc
In your Service Layer process repositories and unit of work processings and expose Data Transfer objects or your domain objects (POCOs) to UI Layer
Use IOC to inject dependencies will help you to minimize dependencies
Create Unit test and Integration tests
Use Continuous Integration and Source control prefer (Distributed: Mercurial)
Useful References:
(Sharp Architecture) http://sharparchitecture.codeplex.com/
(IOC Container) http://www.castleproject.org/container/
(Generic repository) http://code.google.com/p/genericrepository/
NuGet is your friend. Here's a good example of using NuGet to automatically wire in your dependencies and configuration pretty much automatically.
Hope this helps.
Suggestion, don't get hung up on all the automatic stuff that the tutorials are showing you. Microsoft is just trying to show that you can easily get things started if you don't try to do anything unique.
Now for your situation. When you're making a controller, you're wanting to bind that controller with a type of model that you created somewhere. With nHibernate I'm thinking that you'll have manually created these POCO's and that you're using one of the many ways to map those POCO's through nHibernate to your database.
You won't be able to use the Entity Framework options because they're depending upon the features of the framework to provide information on the object, database, etc. Easiest things is to just make a controller that either gives you the options for CRUD or use an empty controller to build up your own ActionResults.
Hope this helps some and good luck with your project.