Unity.wcf and InstanceContextMode.Single - wcf

I am using Unity.WCF to inject dependencies for WCF service. Problem occurs when I set my service to InstanceContextMode.Single.
I found on Google that when InstanceContextMode is set to Single, InstanceProvider is not called. There is also a workaround for this but I was wondering if there is some built-in support for this in Unity.WCF because apparently this is a well known problem.
I found the information here: Enabling InstanceProvider for singleton services.

I will cite Paul Hiles comment on the same question you asked:
Using InstanceContextMode.Single makes your service scale very badly so is best avoided in most cases, particularly if it is just being used to allow AppFabric auto-start. You can safely remove the ServiceBehavior attribute and do it another way.
With Unity.WCF, you can add your initialisation code to the ConfigureContainer method of the WcfServiceFactory class that is created when you add the Unity.WCF NuGet package. This will only be executed once for the lifetime of the service.
BTW, you should not be passing the Unity container into your service. Add any components that your service uses into the constructor (e.g. repositories, helpers etc.) and also register then with Unity using the ConfigureContainer method. When your service is instantiated, the dependencies will be injected automatically.
You may also find article from this MSDN series useful.

Related

How to add Application Insights to ILogger<T> for Unity DI into WCF Service

I have the unfortunate task of updating a WCF project to .NET Framework 4.8 and replacing the existing log4net exception handling with Microsoft Logging and Application Insights.
My approach was to implement Dependency Injection to make instantiation easier and because I am already used to that design approach with .NET Core. As you may know, WCF services adds its own complexity since WCF is responsible for instantiating the services and lower level objects (like custom customUserNamePasswordValidatorType). I was able to handle most of this by implementing a WCF Service Factory and updating the svc markup with it.
I have added Application Insights to the project via the appropriate NuGet packages which updates the web.config with appropriate httpModules for general exception handling. I was even able to add a custom TelemetryInitializer in Application_Start to include a few custom properties in the message.
My problem is getting an instance of ILogger<T> with the attached Application Insights provider into the instantiated service.
At first, I was getting an exception because of the parameterless constructor of Logger<T>. This was fixed by updating my WcfServiceFactory to the following
container
...
.RegisterType<ILoggerFactory, LoggerFactory>(TypeLifetime.Singleton)
.RegisterType(typeof(ILogger<>), typeof(Logger<>), TypeLifetime.Singleton);
This allowed an instance of the logger to be passed into the constructor of each service. However, calls to log messages are never written to App Insights and an inspection of the logger shows zero providers.
My guess is that because a new instance of LoggerFactory is being created, the already existing instance used in the httpModules is ignored.
According to https://github.com/unitycontainer/microsoft-logging, I need to refactor what I am doing and actually create an instance of a LoggerFactory and manually add the desired providers. My issue is that I cannot figure out how to do that with Application Insights. Everywhere else I used it, I would just call the AddApplicationInsights() extension method but that does not seem to be an option here (at least not with Unity).
So I guess my issue boils down to the following questions
Can I get the WcfServiceFactory to use the existing App Insights logging? Maybe establish something in Global.asx?
How can I manually register App Insights as a provider in the WcfServiceFactory including the custom telemetry?
No need to use ILogger if the intention is just to log a custom error. You can log exception on AppInsights directly using the telemetry client, like this:
var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
telemetryClient.TrackException(new Exception("Logged random exception message."));

Ninject Di bindings using a WCF service

I recently created a WCF service library. I am planning on hosting it in IIS. Since I want to reuse my repository layer I decided to go use Ninject in my WCF service as well (I use it in other projects in the solution).
I installed the Ninject Wcf Extensions. I configured it using the NinjectServiceHostFactory in the svc file. I added a Global.asax file to override the CreateKernel() that inherits from NinjectWcfApplication but I am not sure if I am using the bindings correctly. I first started with:
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
But I quickly realized that this does not work since no data was saved to my database. It appears that the WCF service does not use the ASP.NET pipeline. I went ahead and tried both of these as well just to see if my data was committed to the database:
Bind<IUnitOfWork>().To<UnitOfWork>().InThreadScope();
Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
No luck. I then decided to try:
Bind<IUnitOfWork>().To<UnitOfWork>().InSingletonScope();
This worked but I don't want my database context to be shared by every single request that comes in to the WCF service. I then did some research and found the following approach:
Bind<IUnitOfWork>().To<UnitOfWork>().InScope(c => OperationContext.Current);
This works but is it correct? I wan t something to resemble the InRequestScope for a MVC application. Each request to the service should get its own Database context.
I suggest to have a look at the latest build from the CI-Server http://teamcity.codebetter.com
You need Ninject, Ninject.Web.Common, Ninject.Extensions.Wcf
With this version you can use InRequestScope for Wcf.
I am new to Ninject, but I can tell you that OperationContext.Current is the equivalent to HttpContext.Current for web application.
So your first thought was to use .InRequestScope(); (which is equivalent to .InScope(c => HttpContext.Current);)
so I guess that using .InScope(c => OperationContext.Current); for WCF is pretty correct.

DI with WCF -- Where do I initialize the Windsor Container when using WAS hosting?

I was reading an exellent article about how to use dependency injection with WCF Services.
Unfortunately, it only shows how to instantiate and register the Windsor Container in a global.asax file. I'm looking to use WAS for my hosting so global.asax will not get called. Does anyone know where I should register the container? Do I have to extend the WindsorServiceHostFactory an do it in there?
I'm not 100% up to date with development of WCF Facility so it may be already there, but if it's not take a look at this post and the comments.

WCF WinService with Plugins

I have a win32 application that uses client side plugins and uses a Win32 Service via TCP/IP. I would like to also dynamically load assemblies on the WCF service based on the addition of new plugins. Currently I have to add the the ServiceContract and OperationContract to the Services class and IService interface and then re-compile. Is there a way to dynamically load the WCF assemblies and not have to generate the class and interface references? Can these be moved out of the WCF Win32 service into external classes?
I was wondering about this as well, but came to the conclusion that this was not a question of whether or not its possible, but should you do it? Even if you could generate the contract definitions dynamically, you still need to notify the client of the change, they in turn would need to regenerate the proxy in order to interact with the new service definition, and then provide an implementation dynamically. A better approach is to redesign your service so it implements a particular strategy (read Strategy pattern). The contract remains static, but the implementation changes based on client input. That way your service can dynamically load modules without your client being aware of it.
HTH.
Steve

WCF PerCall instance server and Dependency Injection using Prism?

If I have a client/server type of application built using both Prism and WCF, and I would like on the serverside to have the wcf service to be instatiated per call BUT I would like to use dependency injection (using the UnityContainer in Prism). How could I possibly do this? Should I have a single instance service it would be no problem, but are there any hooks in WCF to allow for a delegate to be called whenever a service is supposed to be instantiated and have this instance returned?
Any ideas?
Cheers!
It is possible! WCF provides a plugin to the WCF responsibility chain called an IInstanceProvider. This allows for you to replace the construction with your own.
Someone has implemented this as a service behavior and is available here:
http://code.msdn.microsoft.com/WCFResources/Release/ProjectReleases.aspx?ReleaseId=1252