I have a little bit of a "strange practise" question. The requirement on an architecture of our project is to setup Web API with (if possible) all MVC goodness within WCF project. That means that WCF and Web API web services would be stood up along each other within one project.
Is this even doable? I've given it a short go and found that even merging the web configs of two projects is very hard.
Thank you for your suggestions and comments,
Jakub
I followed these steps and it worked fine:
Make sure your WCF service is working correctly.
Install WebAPI to your project through Nuget Package Manager
Install-Package Microsoft.AspNet.WebApi
Create Controller folder and write your controller class and methods.
Create global.asax file
Register routes for your services in Application_Start method.
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
private void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
"webapi_route",
"/{controller}/{action}/{id}",
new { controller = "controller_name", action = "method_name", id = RouteParameter.Optional }
);
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(service_name)));
}
In fact there are no major restrictions on the use of the two technologies within the same project. By default wcf has a different "pipe line" than asp.net, but until this can be changed. Using the configuration below in web.config it is possible to configure wcf to use the same asp.net pipe line thus sharing the whole life cycle of the objects of the request. But do not believe that this approach is usual for all cases, other factors need to be considered to make that decision, for example, how do you plan to distribute your application? When you release a version of wcf you will also be releasing the web.api, in many cases you may not want this result.
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
It is possible but with losing the MVC goodness (that means that you will not be able to use for example the built in automatic online documentation for your web services).
Just install Web API through NuGet and then register your route in global.asax. Create your api controller and it should be all good.
EDIT 01.02.2017:
This is no longer true. Since Microsoft approach was to merge MVC and Web API controller. Now anything is possible.
Related
I've set up Unity for dependency injection for our project. The project itself is an ASP.NET application that uses both MVC and Web API.
For the database context, I'm using the PerRequestLifetimeManager. This is done so that the different bits of business logic are using the same context (and thus the same transaction).
In order to be able to use the PerRequestLifetimeManager, I've added references to the nuget packages Unity bootstrapper for ASP.NET MVC and Unity bootstrapper for ASP.NET Web API.
For use of this lifetime manager in Web API, the following line has been added to the startup code:
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
The Unity container is set up for both MVC and Web API:
var container = BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(new Microsoft.Practices.Unity.Mvc.UnityDependencyResolver(container));
In building the Unity container, the database context is set up to be resolved per request in the following way:
container.RegisterType<IDataContext>(new PerRequestLifetimeManager(),
new InjectionFactory(c =>
{
// Some code
return new DataContext(/* params */);
}
));
However, it seems that this code is not giving me a new DataContext for each request. It is giving me the same context in different places within a single request (which is fine). However, subsequent (web api) requests are being given the same instance of DataContext where I would expect a new one to be created for each new request. I also would expect the DataContext to be properly disposed of after the request is finished (the class implements IDisposable).
What's going on here? Am I missing a bit of configuration to make this work properly? Or isn't this supposed to work the way I expect it to?
The problem turned out to be that the UnityDependencyResolver was caching the resolved items over several requests. I had to change it to the UnityHierarchicalDependencyResolver and then it started resolving my items properly according to the associated LifetimeManager. The problem initially became more confusing when it appeared that even when using a TransientLifetimeManager, it would still return the same instance.
I found the answer in a different (yet somewhat related) question: using a Handler in Web API and having Unity resolve per request
So all I did was change
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
to
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityHierarchicalDependencyResolver(container);
and all my problems were solved.
I just installed MVC5 and ServiceStack.Host.Mvc into a empty ASP.NET project. MVC for the Routing, Bundling/Minification and ServiceStack for everything else (IoC, Cache, ect.). This site will only be used to deliver views (SPA Islands I call them) and these rendered views will in turn call another ServiceStack RESTful API site.
So my questions is this "Since I have to bootstrap ServiceStack with the AppHostBase which wants an assembly with a Service in it, is there any harm if I just use the current assembly with-out any services as the snippet below illustrates?"
public AppHost()
: base("Website UI", typeof(MyRootNamespace.Global).Assembly) { }
Everything still seems to work in controllers that inherit from ServiceStackController, at least the IoC.
Thank you,
Stephen
Nope, ServiceStack just uses the list of assemblies specified in the AppHost constructor to scan and autowire any IService's it can find in those assemblies, which in this case there just wont be any.
I'm using Asp.net MVC4 with razor. I want to know how to call a controller from one project to another project in a same solution. (I'm new to MVC4)
You can simply add your controllers to another project (class lib or MVC project, etc...) We have a couple projects that share controllers(webAPI as well as MVC). I typically use area constraints for the API controllers and namespace constraints for MVC controllers- especially if you have something like a base HomeController.cs used for some projects and you want to override it in just one particular MVC application project.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Common.MVC.Controllers" }
);
The answer depends a great deal on the concrete problem you are trying to solve.
This is something important to remember when asking questions on Stack Overflow. Sometimes it's more beneficial to ask how to solve your problem rather than how to accomplish the solution you've come up with.
If your goal here is to avoid code replication the simplest answer is to add your second project as a reference to your first. Accessing the controller is still a bit difficult because you need to instantiate it properly so what I'd recommend instead is that you abstract the code you wish to avoid replicating into a third project and have both your MVC projects make calls to the utility class you've created.
Another possibility is that you'd like to have your web services interact with each other while maintaining a client/server relationship. This can be achieved by creating an HTTP web request directed at the port number that Visual Studio selects when you run the second web service project. .Net is capable of doing this but personally I recommend using RestSharp.
You have to seperate projects (because you are testing in local) and then run Destination project and get address (like http://localhost:15823/). After that,
in another project's controller, use the following:
public ActionResult Index()
{
return Redirect("http://localhost:15823/");
}
and run another project.
I kept running my other project whose links I was calling. So in short both applications must be running simultaniously.
I am working on an ASP .NET Mvc 3 App and have installed Ninject.Mvc3 using Nuget. I now have the App_Start folder and then ninject class. I have seen plenty of examples on how to configure NHibernate in the Global.asax file. So how do I configure the session before handing it Ninject if I am using the Web Activator class? Do I just do it like normal in the global.asax?,
Bob Cravens has a nice series of posts on how to do this:
Using the Repository Pattern with MVC and NHibernate
http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/
Using an IoC container (like Ninject) with a NHibernate inside ASP.NET MVC
http://blog.bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/
Any responsible web developer knows that managing / disposing of objects and resources is critical to good web application development. Please make sure and read this bit too :-)
http://blog.bobcravens.com/2010/11/using-ninject-to-manage-critical-resources/
I don't know which example you are refering to. But for most of them you can do it the same way.
Now, in App_Start folder you have a file called NinjectMVC.cs, there is a method:
private static void RegisterServices(IKernel kernel)
{
}
You have to register all your services there, just the same way you did in global.ascx before.
I am creating a new application using asp.net mvc, I'm using munq IOC container as my dependency injection..The issue is i want to create a new project for dependency resolution where i can register all the controllers of mvc project and the repositories of infrastructure project..I have to add Dependency Resolution project as a reference in my mvc app as thats the starting point... but the prob is in order to register the controllers in this separate app i need to have the reference of the mvc in the dependency Resolution project itself...but such a thing is not possible because that would cause a circular reference..
so how to resolve this issue? or what is the best way of managing the dependency resolution?
I don't want to end up registering everything in the Global.asax
Get the latest version from the source tab at Munq.Codeplex.com. This version has a view improvements and it is the version I am most familiar with, and I wrote it.
To prevent circular references for registration, create a class project that includes reverences to Munq.Interfaces and the interfaces and implementations you wish to register.
Create a class that implements IMunqConfig. It has one method void RegisterIn(IIocContainer container). Implement this method.
public class MyRegistration : IMuncConfig
{
public void RegisterIn(IIocContainer container)
{
container.Register<IMyInterface>(c => new MyImplementation());
// OR
container.Register<IMyInterface, MyImplementation>();
// Repeat as required for each thing to register
}
}
Then in global.asax
protected void Application_Start()
{
IocContainer = new Container();
Munq.COnfigurationLoader.FindAndRegisterDependencies(container);
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
This will search the bin directory for any dlls that have classes implementing IMunqConfig and execute the RegisterIn method on each. So just drop the registration dlls into the bin directory and registration happens automagically :)
Matthew
i want to create a new project for dependency resolution where i can
register all the controllers of mvc project and the repositories of
infrastructure project.
I wouldn't register MVC controllers in the same project as your repositories. The MVC app should "own" its composition, including registering its internal dependencies.
Registrations for your infrastructure project should ideally be in that project, especially if it's not something you're going to make available to other projects that use different DI containers. If that project needs to remain DI-agnostic then maybe it might make sense to separate DI registration into a separate project.
But I definitely wouldn't make a service (like your repository) responsible for registering the internal dependencies of its consumers (like your MVC app.)