Sending Emails as Scoped Vs. Transient in ASP.NET Core - asp.net-core

I'm wondering... why does Microsoft use this:
services.AddTransient<IEmailSender, AuthMessageSender>();
In their tutorials for sending e-mails in ASP.NET Core rather than:
services.AddSingleton<IEmailSender, AuthMessageSender>();
Isn't the service supposed to stay the same for the lifetime of the project?
What is the downside of this?
Thanks :)

The reason why they use Transient its because their example is based on Forgot Password.
Forgot password is something secundary it doesnt do part of the main app logic, so it is cheaper in terms of resources to create the service once you need it and after use, discard it. This is the reason they use Transient.
If its a singleton it will be always in memory once it is created and for the forgot passward case which is rare to happens, it is not worth it.

Related

Zend Framework 3 singletons

I'm creating a new application in Zend Framework 3 and i have a question about a design pattern
Without entering in much details this application will have several Services, as in, will be connecting to external APIs and even in multiple databases, the workflow is also very complex, a single will action can have multiple flows depending on several external information (wich user logged in, configs, etc).
I know about dependency injections and Zend Framework 3 Service Manager, however i am worried about instanciating sereval services when the flow will actually use only a few of them in certain cases, also we will have services depending on other services aswell, for this, i was thinking about using singletons.
Is singleton really a solution here? I was looking a way to user singletons in Zend Framework 3 and haven't figured out a easy way since i can't find a way to user the Service Manager inside a service, as I can't retrive the instance of the Service Manager outside of the Factory system.
What is an easy way to implement singletons in Zend Framework 3?
Why use singletons?
You don't need to worry about too many services in your service manager since they are started only when you get them from the service manager.
Also don't use the service manager inside another class except a factory. In ZF3 it's removed from the controllers for a reason. One of them is testability. If all services are inject with a factory, you can easily write tests. Also if you read your code next year, you can easily see what dependencies are needed inside a class.
If you find there are too many services being injected inside a class which are not always needed you can:
Use the ProxyManager. This lazy loads a service but doesn't start it until a method is called.
Split the service: Move some parts from a service into a new service. e.g. You don't need to place everything in an UserService. You can also have an UserRegisterService, UserEmailService, UserAuthService and UserNotificationsService.
In stead of ZF3, you can also think about zend-expressive. Without getting into too much detail, it is a lightweight middleware framework. You can use middleware to detect what is needed for a request and route to the required action to process the request. Something like this can probably also done in ZF3 but maybe someone else can explain how to do it there.

WCF as BLL (Middle Tier) and Security techniques

So bear with me, i am new at MVC and WCF. I already have a set of services (WCF) that exposes my BLL and I am trying to consume those from my MVC.net web application but i am unsure on how to perform security operations here.
These are my app requirements:
Be able to consume WCF services using different credentials for every user on the web application
My BLL (WCF) needs to know what consumer is calling it (right now I only have the MVC app but i am planning to add iOS and Andriod calls to it, so later on i will add REST services to the WCF endpoints) Is there any design pattern for this out there? (or should i just use the soap header to include the caller ID? should i use some sort of caller secret or something?)
I need a security mechanism like Tokens or something so I dont have to pass the username and password on every call of the service method (WCF)
What i have so far:
WCF uses a certificate and and with a custom username validator.
I have manually coded proxies using the contract interfaces instead of generated proxies: But I hate the fact that i have to validate username and password every time a call is made to a WCF service. How in heaven can i use Tokens here? like to know if a given token sent on the soap header is valid or not yet expired? i have searched a lot and no tutorial/code/example is clear enough for me to actually start coding that ;(
I am trying to cache the ChannelFactory but should I? i mean, i will need to cache a channer factory per logged in user per contract ;( is that ok? what can i do here?
Thanks in advance!
Should you cache the ChannelFactory per user per contract?
It depends. There are a couple of considerations. Instantiating a channel factory could take up to 70ms. If you are doing this repeatedly, you will see a noticeable performance hit if you are not caching the ChannelFactory and instantiating one (or more) each time a user makes a http request to your MVC app that results in controller actions calling web services. This would indicate that caching the channelFactory would be beneficial for speed.
On the other hand, depending on the number of users you have, if you are caching a lot of channel factories (in a static dictionary for example), you are going to start to use a non-trivial amount of memory - this may become an issue for you.
You have to decide if the cost of instantiating channel factories on the fly (and correctly closing / aborting them and their contained channels) is too high a price vs increasing memory utilisation in the application pool hosting your MVC app.
Either way, I strongly advise to profile your app before you deploy to production.

Castle windsor - creating and disposing container in WCF services

am planning to implement Castle windsor in WCF layer, which is an ASP.Net project. When I went through the documentation of Castle windsor it was said that we need to create container only once and dispose it after using it. So am struck at this point in my scenario where I need to create container in WCF. I initially thought of putting that on Application_start in global.asax.vb and dispose it in Application_End but application_end will be called when App pool recycles or iis restart etc.
So second thing came to my mind was Session_start and Session_end. Again session end will work for only Inproc type. Also it might get called only after certain amount of idle time.
Third option is to call in each method to create instance and close it after each method. which is not advisable from what I know.
So could you please suggest which is the best way for this.
Thanks in advance
Sai
You would usually configure your IOC container only once per application lifetime, and doing this in Application_Start() seems perfectly reasonable. Reconfiguring it for each new session or for each request most probably is just doing unnecessary work; also, I suspect this could hurt performance.
I don't see anything wrong with Application_Start() / Application_End() approach. If you fear it may leak resources or something like that, then these fears are unjustified.

WCF, Custom Membership Provider and HttpContext

Ok, Im really going to show my stupidity regarding the ASP.NET security model here but here goes.
I have a WCF web service and I have managed to hack my way around to having it pipe through my custom membership provider.
My membership provider overrides "ValidateUser" in which I attempt to load a user object with data from our SQL server instance. All good so far, I retrieve the creds, load the users object and return true if I don't hit any bumps in the road.
At this point, I would usually stuff the user object (or id) into session or actually just some state bag that's accessible for the lifetime of the request. The problem that I am hitting is that HttpContext is null at this point, even though Im using ASP compatability attributes.
What other options do I have at hand?
Cheers, Chris.
EDIT:
Just to clarify what I want to do. I want to pass user credentials to be authenticated on the server, and once this has happened I would like to keep the the details of the authenticated user somewhere that I can access for the lifetime of the service request only. This would be the equiv of Http.Current.Items?
Is there any object that is instantiated per-request that I can access globally via a static property (i.e. in a similar way to HttpContext.Current)? I assumed that OperationContext was the this, but this is also null?
Can this really be such an uncommon problem? Send creds > retrieve user > stuff user somewhere for access throughout processing the request. Seems pretty common to me, what am I missing?
Cheers, Chris.
Basically, with WCF, the preferred best practice solution is to use per-call activation, e.g. each new request / call gets a new instance of the service class, and all the necessary steps like authentication and authorization are done for each request.
This may sound inefficient, but web apps, and in particular web services, ought to be totally stateless whenever possible. Putting stuff in a "state bag" just calls for problems further down the road - how do you know when to invalidate that cached copy of the credentials? What if the user exists your app but the cookie stays on his machine?
All in all, I would strongly suggest trying to get used to the idea of doing these step each and every time. Yes, it costs a little bit of processing time - but on the other hand, you can save yourself from a lot of grief in terms of state management in an inherently stateless environment - always a kludge, no matter how you look at it....
If you still insist on that kludge, you can turn on an ASP.NET "compabitility" mode for WCF which should give you access to HttpContext - but again: I would strongly recommend against it. The first and most obvious limitation is that this ASP.NET compatibility mode of course only works when hosting your WCF service in IIS - which I would again rather not do in production code myself.
To turn on the ASP.NET compatibility mode, use this setting in web.config:
<system.serviceModel>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
and you need to decorate your service implementation (the class implementing the service contract) with a corresponding attribute:
[AspNetCompatibilityRequirements(RequirementsMode=
AspNetCompatibilityRequirementsMode.Allowed)]
class YourService : IYourService
The AspNetCompatibilityRequirementsMode can be NotAllowed, Allowed or Required.
For more information and a more thorough explanation, see Wenlong Dong's blog post on ASP.NET Compatibility Mode

Sharing session between WCF services

I have been working on splitting up the app tier and web tier of a web application. In the app tier, I managed to separate the business logic into a bunch of services exposed using WCF proxies. The problem is that these services talk to another legacy application that uses a large CLR object as its primary means of communication. To keep things quick, I had been keeping a copy of this object in the session after I created it the first time. Now I know that WCF can do sessions, but the session storage is per service whereas my business logic is now split into multiple services (as it should be).
Now the questions:
Is there a way to share session storage between WCF services hosted on the same host?
Is this even something I should be doing?
If not, then what are the best practices here?
This is probably not the first time somebody’s had a large business object on the server. Unfortunately for me, I really do need to cache this object per user (hence the session).
It’s possible the answer is obvious and I'm just not seeing it. Help please!
I think instance context sharing can help
http://msdn.microsoft.com/en-us/library/aa354514.aspx
As far as I understand WCF, it is designed to be as stateless as it could be. In a session you can remember some values in your service, but objects are not meant to live outside the scope of a session.
Therefore, I'd think you are in trouble.
Of course, there might be some way to store and exchange objects between sessions that I don't know (I use WCF, but I don't know very much about it, apart from what I need for myself).
(if there is a way to share objects between services, it probably would only work on services you host yourself. IIS hosting might recycle your service sometimes)
Perhaps you can wrap this object in a singleton service. This is a service with only one instance, which will not be destroyed between calls. Because you need an object for each user, this service has to manage a list of them and the calling services has to provide the needed authentication data (or sessionid). Don't forget a timeout to get rid of unneeded objects...
Create a facade service which hosts the large CLR object on behalf of the other app tier services. It can work as an adapter, allowing more specific session identifiers to the more advanced app tier services you have created. The facade can provide a session identifier, like a GUID, which your app tier services can use to get re-connected with the large CLR object.
This provides a few advantages:
Some of your app tier might not need to know about the CLR object at all. They only communicate with the remote facade.
the 'large CLR object' host retains the session object on behalf of the other services who can now share it.
The app tiers now have a facade through which they talk to the legacy service. As you work to refactor this legacy service, the app tier doesn't have to change.
Depending on your setup, you may be able to host the facade via in proc hosting which will give retain performance boost you are seeking.
Breaking things up into subservices seems like a good idea if you want to be able to spread the app out over a farm. However, it's important to keep in mind that whenever an object crosses the appdomain boundary at the vary least it will have to be copied in memory.
It all depends on how big the object is and what kind of data it holds.
If you don't want to pass the object because it's too large you may want to make a query API for the service which receives it. In this way you could manipulate that object without having to do expensive serialization or remoting.
Keep it simple. Since you already have access to Session in your WCF, you can use the SessionID from there. Now:
Create a static dictionary somewhere, where the Key is your sessionId and the value is the business object you want to store.
Instead of accessing the business object in session, just access the sessionid and get the business object from the Value of your dictionary.
(You can also use some type of caching if you wish, for example System.Web.Caching, that way you don't have to cleanup the dictionary manually)