different db provider without recompile my dll - asp.net-mvc

Hi i am working on asp.net mvc app now.
I want to put all db logic to my mydbprovider.dll
The problem is in design, how can i change only db provider name in my web.config without recompile my own dll ?
I will use such .net providers as (oracle,mssql,postrgree)
Thanks and sorry for my bad english

as soon as you change the web.config then the site's appDomain will restart. This is unavoidable and only happens in the following scenarios:
Change of web.config
change to bin folder
Trigger of
numRecompilesBeforeAppRestart
what you need to do to be able to swap dal layers easily is to program to interfaces. There will be an interface that implements with the correct methods that you want to use and then any associated dal layer (mysql, sqlserver, oracle) will implement those methods
hopefully that will mean you are not bound to a specific implementation of a dal
paul

Related

Accessing NInject kernel from a dependent assembly

I have an ASP.NET MVC 5 project where I need to use a custom web-service based e-mail service (long story! Can't change it, though).
I wrapped up the e-mail web service into a separate assembly and packaged all the dependencies in there.
In my ASP.NET MVC 5 app, I'm using Ninject for dependency injection, and it works really well inside the MVC project - the controllers get their dependencies injected "magically" , and it's a joy to use.
But now: for my e-mail sending component, I'd like to write a "mock" or simulator for use locally when doing development. So basically, I would need to be able to bind the IMailService to both the MailService (real implementation), as well as the MailServiceSimulator (my dummy implementation). Ninject supports that, no problem:
Bind<IMailService>().To<MailService>().Named("Production");
Bind<IMailService>().To<MailServiceSimulator>().Named("Simulator");
BUT: the problem is this: I register all the dependencies with Ninject in the MVC application (in the NinjectWebCommon class in App_Startup) - but I'd like to be able to have a factory class in my "mail service" project that can be told to return a real implementation - or the simulator - for the mail sending component. But how can I get access to the Ninject kernel in order to get the desired service?
Somehow, I'd need to be able to do either
return kernel.Get<IMailService>("Production");
if the real implementation is desired, or
return kernel.Get<IMailService>("Simulator");
if the development-time simulator for the IMailService should be used.
Since my MVC app already uses the "MailService" assembly as a reference, I cannot really make the "MailService" use the "MVC" project as a reference.... so how can I access the Ninject kernel (that gets created inside the "MVC" assembly at startup) from within a referenced "MailService" assembly?? Seems I'm going in circles, one assembly requiring the other and then the other requiring the first one again as a dependency.....
Any ideas?
Accessing the Kernel, or doing DI business, in your MailService project seems like a leaky abstraction.
Assuming the "Production/Simulator" switch is located in the appSettings as a "MailSwitch" setting, you may leave out the named bindings and go for :
Bind<IMailService>().To<MailService>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Production");
Bind<IMailService>().To<MailServiceSimulator>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Simulator");

Accessing a LocalDB within an ASP.NET website from another project in solution

I have an asp.net mvc 5 website using EF, LocalDB and Code First Migrations. Requirements have now dictated that I need a need to add a console application into the mix to do some scheduled work. However this console app must call into the database functionality exposed in the web application. Also of note is that we are using LocalDB for development, but will switch to a 'proper' remote DB for production.
As such I have created a new console application within the project and added a reference to the web application so that I can call its repository functions. I know this probably isn't the best way to handle things.
For whatever reason though, when calling Save Changes on the database context from within the console application, nothing is saved to the LocalDB database. The Save function returns a number indicating that a number of rows were inserted.
I get the feeling I am making a schoolboy error somewhere. What could it be?
i`v used this in the past:
<add name="DefaultConnection"
connectionString="Server=(localdb)\v11.0;Database=WebPortalDb" providerName="System.Data.SqlClient"/>
If you want to use the functionality/database from one Project to another project then use the following::
1) Include the 'ConsoleProjectName.dll' file into your 'MVC' project's reference
2) Use that Dll into the namespace of your file.
(eg. using System.Data.Entity)
in the same way you have to use the DLL into your namespace.
3) make an object of the 'console' application's class and use the methods & other properties defined in that class.
May be this much information will be helpful for you.
This we are doing for n-tired architecture, where there are different layers (i.e. projects) in a solution to be linked with each other.

Maintaining .NET web application

I am considering using .NET MVC for my next web app but one of the requirements is that there should be minimum work involved from the clients side (who will be maintaining the site).
They are used to simple HTML sites where all they have to do in order to make a minor change is to modify an html in notepad and upload it.
What parts of an .NET web app needs to be compiled? Is it only the .cs parts of it? Can all the rest be updated freely by modifying files with e.g. notepad?
Also, in an MVC environment, is more of the view related code in compiled files?
How is this kind of maintenance usually done in such cases where the client will take over the site on delivery (and are not interested in needing VS installed and needing to compile!)?
If you really need a web application, then in order to make changes to the 'application' part, they're going to need to be able to recompile.
If they're going to make visual changes, then your best bet is to provide a method for them to edit the HTML of the site. You can make changes to the views (.aspx files) in ASP.NET MVC without having to recompile. If you make changes to your controllers or your Model, then you'll have to recompile.
If this is a major requirement for your client, you can build the site using ASP.Net Web Forms instead of ASP.NET MVC in which case changes to the .cs files will be compiled on the fly when the page is first accessed. Note that this only applies to the .cs files in your Web Forms project. Any .cs files in referenced assemblies will need to be pre-compiled.
That said, I suspect your client is primarily interested in modifying the look/feel/content of a page, so they would probably be satisfied modifying the .aspx files in either a Web Forms or MVC app.
If they have the budget for it, sounds like the best solution is to build a Content Management System, so they don't have to edit files ever again.

Where to put Entity Framework Data Model in MVC application?

Lets consider default ASP.NET MVC application folder structure, so it's looks like this:
-App_data
-Content
-Controllers
HomeController.cs
-Models
AccountModels.cs
-Scripts
-Views
My question is: Where is the best place to put Entity Framework Data Model (EDMX) file? Is it Models folder? Yes - we know that good solution is to introduce new Project and reference it to MVC application, but lets forget about this now.
For a small project, it should be part of the Model. For a larger product, the repository and the associated model could be in a separate assembly.
Well this is debatable, but i'd vote +1 for the Models folder.
The only other candidate would be App_Data, but this is generally for file-based databases (SQL Server CE .MDF, for example) and files you don't want served by IIS.
As the EDMX is an abstraction of the database, it should go into the Models folder.
If the project gets bigger, you should definetely move your EF Model into another project. To future-proof yourself from this, make your Controllers access the EDMX via Repository/Interfaces, so when you move the DAL over to another project, all you'll have to do is add the reference and add in the using statements.
I would put the EF-model (aka physical model) always in its own assembly or in a "core" assembly outside of main MVC application. The same applies for your business-logic / domain-logic / domain-services / etc. Separate the non-web stuff from the MVC-Web-Application.
This will help you re-use the core part of your app. For example when you need to expose it as a service, a command-line tool, migration-tool, etc.
Because storing this in its own assembly is so easy and takes you a few minutes I highly recommend doing this for each and every tiny app too.
My opinion is that you should create
a separate project for domain objects, datacontracts etc. etc...
Like MyProject.Infrastructure including many folders like
DataContracts, Model, Exceptions etc.
a separate project for DataAccess wich contains the DBContexts and the Repositories, this way you can easily manage migrations later on

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.

Resources