We're using Unity to provide dependency injection within the WCF service layer for our current project, and we have followed examples such as the following to write a service host factory, service host, service behaviour and instance provider:
http://avingtonsolutions.com/blog/post/2008/08/02/Uisng-Unity-with-a-WCF-Service.aspx
The solution works very successfully, but we have need to provide contextual resolution of objects on a per-request basis. So far, we have implemented this by creating a child container within the GetInstance method of the instance provider, adding the contextual registrations to the child container, and using the child container to perform the resolution of the service type. Some registrations in both containers use container controlled lifetimes.
As I do not know the lifetime of the child container, I have concerns about this methodology:
1) Does the child container go out of scope at the end of the GetInstance method and therefore get disposed leading to some of our our container resolved objects being disposed in the middle of our request?
2) Alternatively, does the parent container cling on to the child container for some period of time meaning that it will rapidly fill with child container instances in a high traffic environment?
Can anyone point me in the right direction?
Related
According to the official documentation here:
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#authorization-filters
To implement a custom ActionFilter in ASP.NET Core I have three choices:
SeviceFilterAttribute
TypeFilterAttribute
IFilterFactory
But for all three it is stated that:
Shouldn't be used with a filter that depends on services with a lifetime other than singleton.
So how can I inject scoped services in my custom ActionFilter? I can easily get a scoped service from the current HttpContext like this:
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
ISubscriptionHelper subscriptionHelper =
actionContext.HttpContext.RequestServices
.GetRequiredService<ISubscriptionHelper>();
}
But then I am wondering if I am doing something wrong? What is the correct way to depend on scoped services in a custom ActionFilterAttribute?
Resolving services from the HttpContext.RequestServices will correctly resolve scoped and transient instances without causing any problems such as Captive Dependencies. In case resolved components implement IDisposable, they will be disposed of when the request ends. ASP.NET Core passes on the current HttpContext object to filter's OnActionExecuting method and that HttpContext gives access to the DI Container.
This is completely different from injecting those services into the constructor, because the action filter will be cached for the lifetime of the application. Any dependencies stored in private fields will, therefore, live as long as that filter. This leads to the so called Captive Dependency problem.
Code that accesses the DI Container (the HttpContext.RequestServices is your gateway into the DI Container) should be centralized in the infrastructure code of the startup path of the application—the so called Composition Root. Accessing your DI Container outside the Composition Root inevitably leads to the Service Locator anti-pattern—this should not be taken lightly.
To prevent this, it is advised to keep the amount of code inside the action filter as small as possible and implement the filter as a Humble Object. This means that preferably, the only line of code inside the filter is the following:
actionContext.HttpContext.RequestServices
.GetRequiredService<ISomeService>() // resolve service
.DoSomeOperation(); // delegate work to service
This means all (application) logic is moved to the ISomeService implementation, allowing the action filter to become a Humble Object.
I am using the Service Grid based on Apache Ignite .Net and I am seeking to implement the distributed tracing for requests spanning multiple Ignite services.
To implement that, I need to pass a request id (also known as correlation id) through the entire call chain. So I wonder if there is a way to transparently pass some context information from an Ignite service caller to the target Ignite service without wrapping the method arguments in some form of envelope? That would enable me to keep the method arguments clean.
I see that there is the void Execute(IServiceContext context) method that gives access to some context information on the receiving side. Is there a way to manipulate the context on the client side?
Thank you!
void Execute(IServiceContext context) method is invoked automatically whenever an instance of the service is deployed on a grid node, and ServiceContext instance is created inside the grid on service deployment, so it's not intended to be manipulated somehow from the client side.
In described case some kind of correlation id can be added to the service's methods signatures.
I'm using Simple Injector for IoC and Rebus, service bus, to dispatch events saved in multiple queues (topic).
Rebus needs to be configured with a new SimpleInjectorContainerAdapter for each queue.
var bus = Configure.With(new SimpleInjectorContainerAdapter(container))
In this configuration phase is not possible to pass the same instance of Simple injector container neither the same instance of container adapter (the container rises an error of multiple registration of IBus).
I'm also using SignalR as one of the events ' handlers to dispatch events to the clients.
Following this SignalR configuration tutorial I set up several hub and relative event notifier (one for each bounded context in the application).
Using the classical singleton pattern, as shown in the tutorial example, is easy to pass the same instance of notifier to the various instances of containers:
container.RegisterSingleton(Finishing.Notification.Notifier.Instance);
Now I would like to delegate the instance creation to the Simple Injector container (only one), so I started to follow this tutorial:
container.RegisterSingleton<Finishing.Notification.Notifier>();
container.Register(() => GlobalHost.ConnectionManager.GetHubContext<Finishing.Notification.NotificationHub>().Clients);
The issue is that, in this way, I will have n instance of notifier one for each container instance (deeply regrettable).
I know that I can solve this using a master container as Abstract Factory, but I'm looking for a more specific solution.
Thanks.
Now I would like to delegate the instance creation to the Simple Injector containers
(...)
The issue is this way I will have n instance of notifier one for each container instance.
So you would like for each container to create the singleton instance, but it is a problem that each container holds an instance of the singleton... isn't that a contradiction?
So, I have a viewmodel class in a xamarin project that I inject some dependencies into via ninject binding on app start. One of these is an IDialogService.
When my MainPage in my application changes it raises a property changed event and I rebind the implementation of the dialog service since it is tied to the MainPage.
If my viewmodel has already been created with lets say DialogServiceA and then when MainPage changes we rebind to DialogServiceB, will my viewmodel be using service A or B? I think it is using A and therefore does not display in the UI because it is tied to a MainPage that no longer exists.
So, if this is the case how can I dynamically change my dialog service but then update classes that have already been instantiated without changing everything to get the current dialog service from the container every time its used (therefore not injecting it at all really, and doing more of a servicelocator)
Also, if this approach is completely wrong, set me straight.
You're right. Re-configuration of the container does not affect already instanciated objects.
If you want to change dependencies without re-instanciating the dependent (parent ViewModel) there's a few possibilities for you:
use a factory to instanciate the service every time. Implement an Abstract Factory (Site by Mark Seeman) or use Ninject.Extensions.Factory to do so
instead of injecting a service directly, inject an adapter. The adapter then redirects the request to the currently appropriate service. To do so, either all service can be injected into the adapter, or you can use a factory as with the possibility above.
instead of inject a service directly, inject a proxy. The proxy is quite similar to the adapter, but instead of coding every method / property redirection specifically, you code a generic redirect by an interceptor. Here's a tutorial on castle dynamic proxy
At the end of the day, however, i believe you'll also need a way to manage when to change the service / which it should be. There's probably a design alternative which doesn't rely on exchanging objects in such a manner.. which would make it an easier (and thus better?) design.
Edit: i just saw that you also tagged the question as xamarin-forms. In that case it most likely won't be an option to use either a dynamic proxy nor ninject.extensions.factory (it relies on dynamic proxies, too). Why? dynamic proxy / IL emitting is not supported on all platforms, AFAIR specifically on Apple devices this can't be done.
Say I have a simple WCF application that the client calls in order to get a number. There's not much processing in it and the service contract is attributed as SessionMode=SessionMode.NotAllowed.
When is the constructor called? When is the object destructed? Is a constructor called per request?
Are there any reference documents or resources that have this information? I can't seem to find it.
WCF is hosted by IIS, and thus subject to its lifetime rules. A service class, by itself, will probably be created and destroyed as necessary within the app; the class will be constructed upon receipt of a request, the method called, and the result returned, after which the object will leave scope and be disposed/finalized.
However, the project containing your service looks like an ordinary ActiveServer.NET web app to IIS (check out the Global.asax file that should be in it; it contains a class of type HttpApplication, and represents the entry point for the app that IIS can use to control it), and IIS will maintain a "pool" of these applications to handle requests from multiple clients. As long as requests keep coming in, and IIS doesn't decide an app has gotten "stale" and refreshes it or the entire pool, the application will continue to run. So, any static classes you declare, for instance your singleton IoC container, or anything you add to a derived HttpApplication class that you use as your child type, will remain in memory until the app is recycled.