After getting an advice about using ServiceStack for my asp.net MVC website
(Maintaining state in Asp.Net MVC website), I started implementing it in my project - but some stuff is still unclear for me.
Currently I have two projects: one is the asp.net MVC project and the other is the BL project (a class library that holds all the business logic).
All controllers in the MVC project make calls to classes/functions in the BL project.
For now, the mvc project loads the BL's DLL, but in the future when the website will grow, the BL's project will run on separate machines.
I would like to use ServiceStack for session management/caching and authentication (which both of them usually depended on each other).
My questions:
1) Is it possible to use only these two features without the functionality of message based web service? ServiceStack need to be initialized, and it throws me an error when initialized twice (in both projects).
2) Is it possible to split the implementation of ServiceStack between the two projects? I would like to maintain the process of authentication in the BL project using the ServiceStack's authentication providers, but handle all the UI/cookies by myself (or with the help of ServiceStack) in the mvc project.
3) I would like to use ServiceStack's caching in the BL project, but I guess that I still need to maintain some session cookies to receive the session id. What is the right way to do it? Are there any built-in helper functions for this purpose?
Thanks in advance!
1) Is it possible to use only these two features without the functionality of message based web service? ServiceStack need to be initialized, and it throws me an error when initialized twice (in both projects).
If you install the latest ServiceStack.Mvc NuGet package you will get the base ServiceStackController which is an MVC Controller providing convenient access to ServiceStack's built-in providers. Although you still need to auto-wire your controllers with the dependencies it needs, e.g. an injected ICacheClient.
Although even if you're not using ServiceStack's WebFramework, having an AppHost is a convenient place to register your dependencies. ServiceStack is triggered by ASP.NET's IHttpHandler mappings specified in the Web.config, so if you don't have any mappings specified ServiceStack is never able to be called externally, but the registered dependencies are still able to be accessed internally with:
var cache = AppHost.Resolve<ICacheClient>(); //Get ICacheClient for SS IOC
2) Is it possible to split the implementation of ServiceStack between the two projects?
If you do have an AppHost, you cannot have more than one instance in a host project (by design) since an AppHost should be analogous to a host project where all your service dependencies should be registered and settings configured that apply to your entire web application or service.
You can however split the implementation of your services across multiple assemblies and have ServiceStack scan them all by specifying them in your AppHostBase constructor, e.g:
public class AppHost : AppHostBase
{
public AppHost() : base("My Service",
typeof(AServiceInDll1).Assembly, typeof(AServiceInDll2).Assembly/*, etc.*/){}
}
2) cont. I would like to maintain the process of authentication in the BL project using the ServiceStack's authentication providers, but handle all the UI/cookies by myself (or with the help of ServiceStack) in the mvc project.
Look at the ServiceStack.UseCases CustomAuthenticationMvc example project for an example of using MVC but authenticating with ServiceStack.
3) I would like to use ServiceStack's caching in the BL project, but I guess that I still need to maintain some session cookies to receive the session id. What is the right way to do it? Are there any built-in helper functions for this purpose?
You can use any of ServiceStack's Caching providers just like any other C# class, i.e. have your Business Logic binded to ICacheClient and inject the concrete implementation in your IOC.
For sessions you can use the base.SessionAs<T> method in the ServiceStack.Mvc ServiceStackController to access the session. To Save back the session you can use the IHttpRequest.SaveSession() extension methods. Although both these methods require the ASP.NET context (it uses ASP.NET's HttpContext singleton if not provided) to work since it relies on ServiceStack's ss-id/ss-pid cookies that are automatically instructed to be added on the client (by the server) whenever you access the Session.
If you don't want your business logic services to have a dependency on ASP.NET's System.Web I recommend accessing and saving the session to be done in your controllers and passed to your business logic.
I recommend reading the Sessions Wiki Page for more background info on how ServiceStack's sessions work.
Integration of ASP.NET Context between ServiceStack and ASP.NET or MVC
I'll add this info since it's useful for anyone doing advanced integration between ServiceStack and ASP.NET or MVC as some of ServiceStack's extension methods rely on these built-in types.
You can create a ServiceStack IHttpRequest or IHttpResponse (within any HTTP/Controller request) with:
var ssHttpRequest = System.Web.HttpContext.Current.Request.ToRequest();
var ssHttpResponse = System.Web.HttpContext.Current.Response.ToResponse();
Finally you can create a complete request context (that encapsulates both a IHttpRequest and IHttpResponse) with:
var ssRequestContext = System.Web.HttpContext.Current.ToRequestContext();
Not sure I fully grasp your questions and how you would like to split the projects across multiple servers. I'll try my best to answer your questions...
Is it possible to use only these two features without the functionality of message based web service? ServiceStack need to be initialized, and it throws me an error when initialized twice
It seems like you're trying to run 2 instances of ServiceStack (maybe even 2 websites) within one solution (one in your web project and once in your BL layer). I don't think that's possible. Your BL layer can share ServiceStack libraries and you can configure (within AppHost.Configure method) those in your web project that references your BL project.
Is it possible to split the implementation of ServiceStack between the two projects?
I think the answer is yes, but you would have have one instance of ServiceStack used by both the projects. This would share the Session state across the projects. There might be a way to have two projects with there own instances of ServiceStack...see https://github.com/ServiceStack/ServiceStack/wiki/Self-hosting.
I would like to use ServiceStack's caching in the BL project, but I guess that I still need to maintain some session cookies to receive the session id.
If ServiceStack is being used across both projects you can access all session data in UserSession (https://github.com/ServiceStack/ServiceStack/wiki/Sessions). If you MVC Controllers inherit from ServiceStackController you can use SessionFeature.GetSessionId() to get the session Id. In your ServiceStack Service (classes that implement Service) you can get the session data from using base.Session.
Hope this helps.
Related
I have an existing MVC app where I use Castle Windsor as IoC container. It runs in Azure as a Web App.
We have recently expanded the functionality with a new controller based on ASP.Net Web API.
The container is set up and configured in global.asax
But - due to the different nature of the MVC framework and the Web API framework, specifically how they handle HttpContext, we have some code at the core part of our code, that needs to work according to which controller method was executed. The code for doing this is seperated in two different classes (implementing the same interface).
The solution we have now is to configure the container with both instances, inject both instances to the class, and at runtime figure out (by investigating the HttpContext data) which to execute code on.
But I think that sucks.
Is there any way we can do this better? Can we instruct Castle Windsor to figure out which instance to inject at runtime - based on e.g. a value in the URI?
I have read through the SimpleInjector documentation a few times. But have a few questions.
Context:
3 tier app (presentation (mvc + api controllers), service (business logic), data (repositories, entities, etc)
Unit of Work is a thin wrapper around EF's DbContext
my DbContext and Unit of Work are registered PerWebRequest, using
RegisterWebApiRequest causes an exception, because the Unit of Work is used
outside of Web API requests.
my MVC and Api controllers registered using RegisterWebApiControllers(GlobalConfiguration.Configuration) and RegisterMvcControllers(Assembly.GetExecutingAssembly())
Each controller has one or more services injected into it.
Each service has one or more repositories injected into it.
A service may also have another service injected into it.
I want the same Unit Of Work/DbContext to exist in all my services/repositories.
Questions:
Because I am using services in my MVC controllers as well as API controllers; does that mean I can not use RegisterWebApiRequest in place of RegisterPerWebRequest?
none of my services, repositories, etc, maintain any state, I would get the same functionality using PerWebRequest as Transient; is there any advantage to using PerWebRequest over Transient?
Please read the following q/a: How to configure simple injector container and lifestylse in a MVC web app with WebAPI, WCF, SignalR and Background Tasks. The answer explains that:
Putting your Web API in the same project as your MVC controllers is a bad idea from an architectural perspective.
But if you want to do this, you can use the WebRequestLifestyle in both type of applications. The WebApiRequestLifestyle is meant as lifestyle that works for Web API for both IIS and self-hosted environments, but since you placed the Web API controllers in the same project, you are clearly only interested in IIS-hosted; in that case the WebRequestLifestyle will do just fine.
Because I am using services in my MVC controllers as well as API controllers; does that mean I can not use RegisterWebApiRequest in place of RegisterPerWebRequest?
Both lifestyles use a different way of caching. The WebRequestLifestyle uses the HttpContext.Current.Items dictionary to store its SimpleInjector.Scope instance, while the WebApiRequestLifestyle uses the CallContext class to store the Scope during the lifetime of a single asynchronous operation.
Just as the WebRequestLifestyle can be used while resolving Web API controllers, you can use the WebApiRequestLifestyle (or the underlying ExecutionContextScopeLifestyle) for MVC controllers as well. But if you want this, you will create your own IDependencyResolver implementation for MVC that will explicitly start and end an ExecutionContextScope. The absense of a Scope stored in the CallContext is the reason resolving MVC controllers fails when registering services using the WebApiRequestLifestyle. But while it's possible to use the WebApiRequestLifestyle in MVC, the otherway around is much easier, since no custom code is required.
none of my services, repositories, etc, maintain any state, I would get the same functionality using PerWebRequest as Transient; is there any advantage to using PerWebRequest over Transient?
If services don't have state, it doesn't matter what lifestyle they have. The only restriction is that they have dependencies that have a lifestyle that is equal to or longer than their own. Violating this restriction is called Captive Dependencies and can cause all kinds of trouble. Because captive dependencies are bad, Simple Injector v3 checks and prevents this for you.
Although you can probably make all objects in your configuration scoped (non-transient), making them transient is usually easier to configure, and might result in better performance (although you will probably never notice the difference in real life).
I am currently developing an ASP.Net MVC web application that requires username and password authentication. I started looking into using ASP.Net Identity for this however I have a very important requirement, the requirement is that the web application itself has no direct access to any databases, all DB Access is to be exposed to the application via an internal REST service. This is due to certain security polices we follow.
I realise that ASP.Net identity is capable of supporting external authentication methods but my question is split into 2 parts.
1) How would I configure ASP.Net Identity to use my custom REST service for authentication?
2) How would I go about developing a service that can be used by Identity for authentication ? (what would need to be returned from the service to ASP.Net Identity)
Any help on this would be most appreciated.
I just did what you are asking about. First, as FPar suggested, you need to implement an IUserStore and pass that to your UserManager. Your custom IUserStore will implement the interface, I used Resharper to generate stubs, but instead of using entity framework, you will use HttpClient to make calls to your REST service.
The REST service will have one action on a controller, I called my identityController, for each of the interface methods you actually need. I implemented the userstore, userloginstore and the rolestore, with code for about 10 calls I actually used. The identitycontroller then is what actually accesses the database.
I also retained the fully async pattern, using async REST calls and Database looks, both with and without entity framework. A shortened version of my data access code is in another question here, regarding IUserLoginStore::AddLoginAsync. In that class I actually used the original entityframework implementation of the user store for part of work, and eventually settled on plain (except for async) ado.net for the parts I couldn't make work that way. The tables are simple enough, using your ORM of choice would not take a lot of time.
Good luck!
You want to implement your own IUserStore and then pass a reference to the UserManager. Look into the Startup and the IdentityConfig files in the standarad ASP.NET MVC with individual user account authentication, to see, how to use them.
You can look here for an IUserStore implementation with entity framework. This is a template, you could start from and change it to your needs. However, you don't have to implement all interfaces, just implement the interfaces, you really need. The UserManager is able to handle that (it throws an exception, if you call a method, that requires an interface, that you don't implement.)
These are two excellent articles on this subject:
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
http://www.codeproject.com/Articles/762428/ASP-NET-MVC-and-Identity-Understanding-the-Basics
I've desgined my ASP.NET MVC application using the Domain Driven Design, and I got the following projects:
MyApp.Core - the app core, contains the domain models etc.
MyApp.Infrastructure - the app main infrastrucutre, contains implementation for the domain model storing (repos etc.) using EF.
MyApp.Web.Core - domain models, services declaration (interfaces) and such only for web (e.g. IFormAuthenticationTicketSupplier, IOAuthAuthenticationProvider etc.)
MyApp.Web.Infrastructure - web implementation
MyApp.Web.UI - ASP.NET MVC standard application.
This application should be used by enterprise with multiple servers, etc. Currently, the application calls a service in the infrastructure layer at the controllers, which uses Repositories and EF. I can connect to the DB server using the connection string.
When digging about this topic at Google, I've read that some approches taken when creating an enterprise application are create an Application server and Web server. In the application server - storing a WCF service, and in the web server just calling it.
I'd like to know if I should do so (if creating a WCF service is the right and required approch when dealing with enterprises):
- Why should someone not just use the Services in the controllers and instead use an API?
- In case I'm using an API, it won't slow down the response? since even if the computers are on the same network, I still open an HTTP request.
- If I should use WCF, or ASP.NET WebAPI?
Thanks for any feedback and help!
First, regarding your projects, is there a need to split up MyApp.Web.Core, MyApp.Web.Infrastructure and MyApp.Web.UI? Sure they may be separate responsibilities, but sometimes dependency hygiene trumps encapsulation. You can always leave them in separate folders and namespaces. I wouldn't extract something into a separate project unless I needed to reference that as a library from elsewhere.
As far as the application service, that also depends on your needs. If the only place that would call that application service is the ASP.NET MVC app, then there isn't much of a need to extract an application service. There are some benefits however. One is that you don't have to worry about all of the dependencies required for a service - you just references it via Url. And of course you have the ability to call the service from places other than the controller, although the MVC controller can act as a pure HTTP service as well. You also have the ability to deploy updates to a specific service without releasing the MVC app. But you do have the burden of maintaining a separate service. If you do go that route, go with the WebAPI, WCF is just too much abstraction.
I have a prototype ASP.NET-MVC website which uses Ninject as a IoC container. All service-classes and repository-classes used by MVC Controllers are properly injected by Ninject. This is great.
The next thing I need to add there is Silverlight (version 3 to be more precise).
Silverlight will be connecting to my server using WCF service, hosted in ASP compatibility mode, to the same ASP.NET-MVC website.
What Silverlight needs is to 'download'/'get' a kind of ViewModel using WCF (the better name would be Client-Side Model). This is also possible - I imported WCF service and setup all security-related xml configuration files.
Here is the stuff I want to know....
Is that OK that model returned by WCF service is rather complex and includes arrays and inheritance (at array items' level)... or maybe there is another and better way to send it from server to client?
At Server-Side for regular asp-mvc stuff all service-classes used by controllers are injected by Ninject. How to inject services for WCF-service classes?
Do WCF service has an access to HttpContext.Current.Items? I need to grab from here logged User Id and a few profile-related data (regular forms auth. stuff).
EDIT
Ad 3. It's possible enabling AspNetCompatibilityRequirements
Has anybody ideas for point 2?
For the 1st Question.
Yes it is okay to return a complex structure, provided you have explicitly applied the '[DataMember]' attribute to each and every needed property of the Object/s.