How do you consume WCF services from a console app using Autofac? - c#

So I have a console application in which I am using Autofac.
I have set up my console application as follows:
I have a class I call ContainerConfig - In this I have all my builder registrations:
public static class ContainerConfig
{
public static IContainer Configure()
{
var builder = new ContainerBuilder();
builder.Register(c => new MatchRun()).As<MatchRun>).SingleInstance();
builder.RegisterType<AuditLogic>().As<IAuditLogic>();
builder.RegisterType<AuditRepository>().As<IAuditRepository>();
builder.RegisterType<ValidationLogic>().As<IValidationLogic>();
return builder.Build();
}
}
I call my main applcation as follows:
private static void Main(string[] args)
{
var container = ContainerConfig.Configure();
using (var scope = container.BeginLifetimeScope())
{
var app = scope.Resolve<IApplication>();
app.Run(args);
}
}
The issue is that I have a connected WCF service. This is my AuditRepository. (FYI - I have not touched WCF for years so I have forgotten most of what I knew).
Its currently constructed to create and dispose of the the proxy each time I make a call to that client. This functions - mostly.
Looks like this:
public string GetStuff(string itemA, string itemB)
{
try
{
GetProxy();
return _expNsProxy.GetStuff(itemA, itemb);
}
catch (Exception ex)
{
IMLogger.Error(ex, ex.Message);
throw ex;
}
finally
{
// CloseProxyConn();
}
}
What i am wondering is can I do this better with Autofac - creating a single instance vs the constant open close - or am I just totally crazy? I know I am not fully asking this the right way - not 100% sure how to actually word the question.
Thanks

The approach to always create a new proxy and close it after each call is good for WCF.
Otherwise you can run into issues. For example if one service call fails the channel created by the proxy goes into a faulted state and you can not do more calls on it just abort it. Then you need to create a new proxy. Also you can have threading issues if you call the same proxy from multiple threads simultaneously.
Check also this documentation with a sample of how to handle errors correctly when calling WCF services.
There is an Autofac.Wcf package that can help you with the creation and freeing of channels. Check the documentation here. It uses the dynamic client generation approach where you just give the interface of your WCF service and it generates the channel based on the interface. This is a bit more low level approach so you will have to understand more what is going on. The generated client class does this for you in the background.
You need two registrations one for the channel factory that is a singleton:
builder
.Register(c => new ChannelFactory<IYourWcfService>(
new BasicHttpBinding(), // here you will have to configure the binding correctly
new EndpointAddress("http://localhost/YourWcfService.svc")))
.SingleInstance();
And a factory registration that will create the channel from the factory every time you request the service:
builder
.Register(c => c.Resolve<ChannelFactory<IYourWcfService>>().CreateChannel())
.As<IIYourWcfService>()
.UseWcfSafeRelease();

Related

How to correctly and safely dispose of singletons instances registered in the container when an ASP.NET Core app shuts down

I am looking for guidance on how to correctly and safely dispose of registered singleton instances when my ASP.NET Core 2.0 app is shutting down.
According to the following document, if I register a singleton instance (via IServiceCollection) the container will never attempt to create an instance (nor will it dispose of the instance), thus I am left to dispose of these instances myself when the app shuts down.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.0 (2.1 has the same guidance)
I enclose some pseudo code that illustrates what I am trying to achieve.
Note I am having to maintain a reference to IServiceCollection since the IServiceProvider provided to the OnShutDown method is a simple service locator and doesn't give me the ability to execute complex queries.
When the app shuts down I want a generic way to ensure all singleton instances are disposed. I could maintain a reference to all these singleton instances directly but this doesn't scale well.
I originally used the factory method which would ensure the DI managed the lifetime of my objects, however, the execution of the factory method happened at runtime in the pipeline of handling a request, which meant that if it threw an exception the response was 500 InternalServerError and an error was logged. By creating the object directly I am striving for faster feedback so that errors on startup lead to a automatic rollback during the deployment. This doesn't seem unreasonable to me, but then at the same time I don't to misuse the DI.
Does anyone have any suggestions how I can achieve this more elegantly?
namespace MyApp
{
public class Program
{
private static readonly CancellationTokenSource cts = new CancellationTokenSource();
protected Program()
{
}
public static int Main(string[] args)
{
Console.CancelKeyPress += OnExit;
return RunHost(configuration).GetAwaiter().GetResult();
}
protected static void OnExit(object sender, ConsoleCancelEventArgs args)
{
cts.Cancel();
}
static async Task<int> RunHost()
{
await new WebHostBuilder()
.UseStartup<Startup>()
.Build()
.RunAsync(cts.Token);
}
}
public class Startup
{
public Startup()
{
}
public void ConfigureServices(IServiceCollection services)
{
// This has been massively simplified, the actual objects I construct on the commercial app I work on are
// lot more complicated to construct and span several lines of code.
services.AddSingleton<IDisposableSingletonInstance>(new DisposableSingletonInstance());
// See the OnShutdown method below
this.serviceCollection = services;
}
public void Configure(IApplicationBuilder app)
{
var applicationLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
applicationLifetime.ApplicationStopping.Register(this.OnShutdown, app.ApplicationServices);
app.UseAuthentication();
app.UseMvc();
}
private void OnShutdown(object state)
{
var serviceProvider = (IServiceProvider)state;
var disposables = this.serviceCollection
.Where(s => s.Lifetime == ServiceLifetime.Singleton &&
s.ImplementationInstance != null &&
s.ServiceType.GetInterfaces().Contains(typeof(IDisposable)))
.Select(s => s.ImplementationInstance as IDisposable).ToList();
foreach (var disposable in disposables)
{
disposable?.Dispose();
}
}
}
}
It's the DI's job to dispose of any IDisposable objects it creates, whether transient, scoped or singleton. Don't register existing singletons unless you intend to clean them up afterwards.
In the question's code there's no reason to register an instance of DisposableSingletonInstance. It should be registered with :
services.AddSingleton<IDisposableSingletonInstance,DisposableSingletonInstance>();
When the IServiceCollection gets disposed, it will call Dispose() on all the disposable entities created by it. For web applications, that happens when RunAsync() ends;
The same holds for scoped services. In this case though, the instances will be disposed when the scope exits, eg when a request ends.
ASP.NET creates a scope for each request. If you want your service to be disposed when that request ends, you should register it with :
services.AddScoped<IDisposableSingletonInstance,DisposableSingletonInstance>();
Validation
For the latest edit :
By creating the object directly I am striving for faster feedback so that errors on startup lead to a automatic rollback during the deployment.
That's a different problem. Deployment errors are often caused by bad configuration values, unresponsive databases etc.
Validating Services
A very quick & dirty way to check would be to instantiate the singleton once all startup steps are complete with :
services.GetRequiredService<IDisposableSingletonInstance>();
Validating Configuration
Validating the configuration is more involved but not that tricky. One could use Data Annotation attributes on the configuration classes for simple rules and use the Validator class to validate them.
Another option is to create an IValidateable interface with a Validate method that has to be implemented by each configuration class. This makes discovery easy using reflection.
This article shows how the IValidator interface can be used in conjunction with an IStartupFilter to validate all configuration objects when an application starts for the first time
From the article :
public class SettingValidationStartupFilter : IStartupFilter
{
readonly IEnumerable<IValidatable> _validatableObjects;
public SettingValidationStartupFilter(IEnumerable<IValidatable> validatableObjects)
{
_validatableObjects = validatableObjects;
}
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
foreach (var validatableObject in _validatableObjects)
{
validatableObject.Validate();
}
//don't alter the configuration
return next;
}
}
The constructor gets all instances that implement IValidatable from the DI provider and calls Validate() on them
That's not accurate. Singletons are disposed at app shutdown, though it's kind of not actually all that relevant because when the process stops, everything goes with it anyways.
The general rule of thumb is that when using DI, you should use DI all the way down, which then means you'll almost never be disposing on your own, anywhere. It's all about ownership. When you new stuff up yourself, you're also then responsible for disposing of it. However, when using DI, the container is what's newing things up, and therefore, the container and only the container should then dispose of those things.
Thanks for the responses Panagiotis Kanavos and Chris Pratt and for helping to clarify how best to deal with this scenario. The two take away points are this:
Always strive to let the container manage the life cycle of your objects so when the app is shutdown the container will automatically dispose of all objects.
Validate all your configuration on app startup before it is consumed by objects registered in the container. This allows your app to fail fast and protects your DI from throwing exceptions when creating new objects.

Where to put my IoC Container configuration in Service Fabric Service?

I was thinking in placing the IoC Container dependencies configuration under RunAsync method in the Service class but I have a bad feeling that's not the right place to go..
Is there any convention in Azure Service Fabric Services to place this type of configurations without causing any sort of conflicts?
Also, where would you place the dispose call?
Note: I'm using Simple Injector for this but other examples from other IoC containers should do too.
You can create your IoC container in the startup code in program.cs. When you register a service, you can pass it a callback method that is passed the ServiceContext. Once you have the ServiceContext, you can use it to gain access to your application configuration for connection strings and such.
Here's some code I use to create a Ninject kernel.
namespace AccountCommandService
{
internal static class Program
{
private static void Main()
{
try
{
ServiceRuntime.RegisterServiceAsync("AccountCommandServiceType",
context =>
{
// Create IoC container
var kernel = new ServiceKernel(context);
// Create Service
return new AccountCommandService(context,
kernel.Get<IAccountDataContextFactory>(), // Pull a DBContext factory from the IoC
);
}).GetAwaiter().GetResult();
Thread.Sleep(Timeout.Infinite);
}
catch (Exception e)
{
ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
throw;
}
}
}
}

How to inject with simple injector

I am struggling to determine if this is the correct method for injecting dependencies from my Console Application Main method into my primary application class instance.
I have the following code:
Program Class
static void Main(string[] args)
{
var container = new SimpleInjector.Container();
// Registrations here.
container.Register<ILogger, FileLogger>();
//Verify the container.
container.Verify();
ILogger log = container.GetInstance<ILogger>();
log.Info("Logging From Main Method");
//Start Main Agent
MainAgent agent = new MainAgent(log);
agent.Start();
}
Main Agent Class
public class MainAgent
{
private ILogger log;
public MainAgent(ILogger _log)
{
log = _log;
}
public void Start()
{
//Main Application Code here.
Console.WriteLine("main Agent Started.");
log.Info("Logging through logger in MainAgent Class");
Console.ReadLine();
}
}
I come from a background of writing DotNetCore applications in ASP.Net Core, so I am used to how the DI works with that, registering a service into the pipeline, and them all being available for me to cherry pick in each controller's Constructor.
My worry is I may have 20-30 services, all of which will all need to be injected in as parameters each time I “New Up” a new instance of a class for them to be avaliable to the constructor in my new class.
Am I missing some magical feature which will just make all my registered services available in any newly initialized constructor for me to reference as I do with ASP.Net Core?
No, there is no magic.
What you are missing is that AspNetCore automatically resolves your controller under the covers, which resolves the entire object graph of dependencies that controller has (that is, any dependencies of the controller, dependencies of those dependencies, etc.)
Similarly, in a console app, you need to resolve the entire object graph (usually at startup).
static void Main(string[] args)
{
// Begin Composition Root
var container = new SimpleInjector.Container();
// Registrations here.
container.Register<ILogger, FileLogger>();
container.Register<IMainAgent, MainAgent>();
//Verify the container.
container.Verify();
// End Composition Root
MainAgent agent = container.GetInstance<IMainAgent>();
//Start Main Agent
agent.Start();
}
Effectively the "agent" is should be considered to be the entire application. The console is just a shell to set everything in motion. Do note that it would probably be sensible in most situations to pass in the args from the console app, so they can be parsed and responded to by the "agent" as appropriate.
agent.Start(args);
Am I missing some magical feature which will just make all my registered services available in any
Simple answer yes you are SimpleInjector supports direct object creation
var agent = container.GetInstance<MainAgent>();
With out the need to register the instance at all.
You can make an interface and then register like you do ILogger but making the method virtual and using directly the class name is also fine. You can read more on the subject here

Disposing/Cleaning up web service proxies

What is the best practise for Disposing/Cleaning up a web service proxy instance after synchronous usage?
How does the answer differ if the proxy class is derived from SoapHttpClientProtocol versus ClientBase<T>?
Background
I'm trying to figure out why one of my WCF web services sometimes seems to get into a state where it no longer reponds to service calls. Basically it seems like it hangs and for now I don't really have any hard data to figure out what's going on when this occurrs.
One thing that I suspect might be an issue is the fact that this WCF service is itself doing web service calls to a few other services. These other services are called (synchronously) using proxies that are derived from SoapHttpClientProtocol (made using wsdl.exe) and at this time these proxy instances are left to be cleaned up by the finalizer:
...
var testProxy = new TestServiceProxy();
var repsonse = testProxy.CallTest("foo");
// process the reponse
...
So should I simply wrap these up in a using(...) { ... } block?
...
using(var testProxy = new TestServiceProxy())
{
var repsonse = testProxy.CallTest("foo");
// process the reponse
}
...
What if I were to change these proxy classes to be based on ClientBase<T> by recreating them using svcutil.exe? Based on my research so far, it seems the Dipose() method of classes derived from ClientBase<T> will internally call the Close() method of the class and this method might in turn throw exceptions. So wrapping a proxy based on ClientBase<T> in a Using() is not always safe.
So to reiterate the question(s):
How should I clean up my web service proxy after using it when the proxy is based on SoapHttpClientProtocol?
How should I clean up my web service proxy after using it when the proxy is based on ClientBase<T>?
Based on my best efforts to find the answer to this question, I'd say that for SoapHttpClientProtocol based proxies (regular .asmx web service proxies) the correct way is to simly wrap it in using():
using(var testProxy = new TestAsmxServiceProxy())
{
var response = testProxy.CallTest("foo");
// process the reponse
}
For proxies based on ClientBase<T> (WCF proxies) the answer is that it should not be wrapped in a using() statement. Instead the following pattern should be used (msdn reference):
var client = new TestWcfServiceProxy();
try
{
var response = client.CallTest("foo");
client.Close();
// process the response
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}

Dealing with concurrency and complex WCF services interacting with objects of the overall application

I am enjoying creating and hosting WCF services.
Up until now I can create services defining contracts for the service and data (interfaces) and defining hosts and configuration options to reach them (endpoint specifications).
Well, consider this piece of code defining a service and using it (no mention for endpoints that are defined in app.config not shown here):
[ServiceContract]
public interface IMyService {
[OperationContract]
string Operation1(int param1);
[OperationContract]
string Operation2(int param2);
}
public class MyService : IMyService {
public string Operation1(int param1) { ... }
public string Operation2(int param2) { ... }
}
public class Program {
public static void Main(stirng[] args) {
using (ServiceHost host = new ServiceHost(typeof(MyService))) {
host.Open();
...
host.Close();
}
}
}
Well, this structure is good when creating something that could be called a Standalone service.
What if I needed my service to use objects of a greater application.
For example I need a service that does something basing on a certain collection defined somewhere in my program (which is hosting the service). The service must look into this collection and search and return a particular element.
The list I am talking about is a list managed by the program and edited and modified by it.
I have the following questions:
1) How can I build a service able to handle this list?
I know that a possible option is using the overloaded ServiceHost constructor accepting an Object instead of a Type service.
So I could pass my list there. Is it good?
[ServiceContract]
public interface IMyService {
[OperationContract]
string Operation1(int param1);
[OperationContract]
string Operation2(int param2);
}
public class MyService : IMyService {
private List<> myinternallist;
public MyService(List<> mylist) {
// Constructing the service passing the list
}
public string Operation1(int param1) { ... }
public string Operation2(int param2) { ... }
}
public class Program {
public static void Main(stirng[] args) {
List<> thelist;
...
MyService S = new MyService(thelist)
using (ServiceHost host = new ServiceHost(S)) {
host.Open();
...
host.Close();
// Here my application creates a functions and other that manages the queue. For this reason my application will edit the list (it can be a thread or callbacks from the user interface)
}
}
}
This example should clarify.
Is it the good way of doing? Am I doing right?
2) How to handle conflicts on this shared resource between my service and my application?
When my application runs, hosting the service, my application can insert items in the list and delete them, the same can do the service too. Do I need a mutex? how to handle this?
Please note that the concurrency issue concerns two actors: the main application and the service. It is true that the service is singleton but the application acts on the list!!!
I assume that the service is called by an external entity, when this happens the application still runs right? Is there concurrency in this case???
Thankyou
Regarding point 2, you can use Concurrent Collections to manage most of the thread safety required.
I'm not sure what you mean by point 1. It sounds like you're describing basic polymorphism, but perhaps you could clarify with an example please?
EDIT: In response to comments you've made to Sixto's answer, consider using WCF's sessions. From what you've described it sounds to me like the WCF service should be sat on a seperate host application. The application you are using currently should have a service reference to the service, and using sessions would be able to call an operation mimicking your requirement for instantiating the service with a list defined by the current client application.
Combine this with my comment on exposing operations that allow interaction with this list, and you'll be able to run multiple client machines, working on session stored Lists?
Hope that's explained well enough.
Adding the constructor to MyService for passing the list certainly will work as you'd expect. Like I said in my comment to the question however, the ServiceHost will only ever contain a single instance of the MyService class so the list will not be shared because only one service instance will consume it.
I would look at a dependency injector (DI) container for WCF to do what you are trying do. Let the DI container provide the singleton list instance to your services. Also #Smudge202 is absolutely correct that using the Concurrent Collection functionality is what you need to implement the list.
UPDATE based on the comments thread:
The DI approach would works by getting all of an object's dependencies from the DI container instead of creating them manually in code. You register all the types that will be provided by the container as part of the application start up. When the application (or WCF) needs a new object instance it requests it from the container instead of "newing" it up. The Castle Windsor WCF integration library for example implements all the wiring needed to provide WCF a service instance from the container. This posts explains the details of how to use the Microsoft Unity DI container with WCF if you want to roll your own WCF integration.
The shared list referenced in this question would be registered in the container as an already instantiated object from your application. When a WCF service instance is spun up from the DI container, all the constructor parameters will be provided including a reference to the shared list. There is a lot of information out there on dependency injection and inversion of control but this Martin Fowler article is a good place to start.

Categories

Resources