Disposing of database connection from within WCF - c#

I have a WCF service hosted in IIS:
[WebServiceLogging]
public class ComplaintService : IComplaintService
This service has the WebServiceLogging attribute that does straightforward request/response logging into the database:
public class WebServiceLoggingAttribute : Attribute, IServiceBehavior {
SomeDatabaseConnection connection; // unmanaged resource
... interface implementations
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) {
IDispatchMessageInspector messageInspector = new WebServiceLogger(connection, _operations);
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in dispatcher.Endpoints)
{
DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
dispatchRuntime.MessageInspectors.Add(messageInspector); // pass the logger into WCF.
}
}
}
}
Logging work is done from the WebServiceLogger, which uses the SomeDatabaseConnection unmanaged resource:
public class WebServiceLogger : IDispatchMessageInspector {
public object AfterReceiveRequest {
... gather Request data.
}
public void BeforeSendReply {
... gather Request data.
... Log using ADO.NET
... Dispose of Command object. No Connection closing!
}
}
I need to close the connection within WebServiceLogger once I'm done with logging. Options I've identified are:
Implement an IDisposable on WebServiceLogging class and do a Dispose() there or
Dispose of SomeDatabaseConnection directly from WebServiceLogger.BeforeSendReply()
My questions here are:
IDispatchMessageInspectors (such as WebServiceLogger) passed into dispatchRuntime.MessageInspectors - I've noticed that this object is not recreated per each request, but rather only once on the first request towards my service. How are such objects disposed of? Does WCF call `Dispose()˙ on them or should I use some other approach here?
Since we're at it, I have a nagging thought that perhaps using unmanaged resources in an Attribute is not such a good idea. Googling for c# attribute dispose didn't yield any results (there is one result on destructor, though). Any critiques on this approach?

Open and close a connection inside the BeforeSendReply method; i.e. make it a local variable (with a using-block, etc.).
Something like this:
public void BeforeSendReply {
... gather Request data.
using (var conn = new SqlConnection(...)) {
... Log using ADO.NET
}
}
The overhead is usually irrelevant (as ADO.NET uses connection pooling and won't really open/close a brand new connection). Second, and most importantly, that way you don't have to think about how your interceptor instance is used/called in a multithreaded (parallel requests) scenario.
That also matches better the unit of work pattern, that would be typically used if you did the same thing in the implementation method of an OperationContract. If you think about it, the interceptor points (AfterReceiveRequest and BeforeSendReply) are really just extensions of such method implementations (kind of AOP).

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.

How to find out where my legacy application using NHibernate is leaking memory

I have a legacy application that I'm maintaining that is leaking memory.
I am reasonably confident that the source is the session management/dependency injection code. It uses Simple Injector and NHibernate.
To start, here are some helper classes and interfaces we use:
public class SessionFactory : Dictionary<string, Func<ISession>>,Helpers.ISessionFactory, IDisposable
{
public ISession CreateNew(string name)
{
return this[name]();
}
public void Dispose()
{
foreach (var key in Keys)
{
this[key]().Close();
this[key]().SessionFactory.Close();
}
}
}
public interface ISessionFactory
{
ISession CreateNew(string name);
}
Here is what the container initialization looks like:
private static void InitializeContainer(Container container)
{
var connectionStrings = System.Configuration.
ConfigurationManager.ConnectionStrings;
var sf1 = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db1"].ConnectionString
).BuildSessionFactory();
var sf2 = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db2"].ConnectionString
).BuildSessionFactory();
var sf3 = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db3"].ConnectionString
).BuildSessionFactory();
container.Register<ISessionFactory>(() =>
new SessionFactory
{
{"db1", sf1.OpenSession},
{"db2", sf2.OpenSession},
{"db3", sf3.OpenSession}
}, Lifestyle.Scoped);
}
Then, inside our base controller (other controllers inherit from it), this happens:
protected BaseController(ISessionFactory factory)
{
this.factory = factory;
db1Session = factory.CreateNew("db1");
db2Session = factory.CreateNew("db2");
db3Session = factory.CreateNew("db3");
}
From there, all of our methods can use a session from any database. Some request methods use multiple database sessions to complete their tasks. This project does not utilize the repository pattern at this point -- rewriting it would be an expensive operation. Is there any obvious memory leak I'm missing in this code?
I find your design very suspicious. First of all, your factory is leaking connections, since although you try to dispose it, the only thing you achieve is disposing things you just opened during disposal; this isn't very useful and means the already created connections will not be closed. Second, a design where your application requests the proper connection using a string based approach is error prone. Your application is probably dealing with multiple database schemas, where each connection relates to a certain schema. This means that connections aren't interchangeable and this warrants the use of a unique abstraction per schema. So instead of having one generic ISessionFactory abstraction that tries to serve all consumers (and currently fails), make things explicit by giving each unique schema its own abstraction. For instance:
public interface IDb1SessionProvider
{
ISession Session { get; }
}
public interface IDb2SessionProvider
{
ISession Session { get; }
}
public interface IDb3SessionProvider
{
ISession Session { get; }
}
By lack of context, I named the interfaces IDbXSessionProvider, but I bet you can come up with a better name.
This might look weird, since all interface have the same method signature, but remember that they have each a very different contract. The Liskov Substitution Principle describes that they should not share the same interface.
An implementation for such provider can be made as follows:
public class FuncDb1SessionProvider : IDb1SessionProvider
{
Func<ISession> provider;
public FuncDb1SessionProvider(Func<ISession> sessionProvider) {
this.sessionProvier = provider;
}
public ISession Session => provider();
}
And you can register such implementation in Simple Injector as follows:
var factory = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db1"].ConnectionString)
.BuildSessionFactory();
var session1Producer = Lifestyle.Scoped.CreateProducer<ISession>(
factory.OpenSession, container);
container.RegisterSingleton<IDb1SessionProvider>(
new FuncDb1SessionProvider(session1Producer.GetInstance));
What this code does is creating a scoped InstanceProducer for the db1 session. The scoped InstanceProducer will ensure only one instance of that session is created during a certain scope (usually a web request) and it will ensure that the ISession implementation is disposed (if it implements IDisposable). The call to InstanceProducer.GetInstance() is wrapped in the FuncDb1SessionProvider. This session provider will call forward the creation of the session to the wrapped delegate.
With this design you can let your application code depend on the IDb1SessionProvider and that code can use it without the need to dispose it. Every call to IDb1SessionProvider.Session within the same session will ensure you get the same session and Simple Injector guarantees disposal on the end of the request.
It looks like you have invented your own interface called ISessionFactory. Given that you are using NHibernate which also provides an interface under this name, I would argue that it's VERY unfortunate to use the same names in your own code. You should pick a different name for your own interface and class to avoid confusion.
As for the question itself, NHibernate's ISessionFactory.OpenSession() does exactly that. It will open and return a session. There is no basis to assume that it will do something magic with regards to reuse or scoping.
To have NHibernate assist with contextual sessions, you need to configure the proper "context provider" and use, among other things, ISessionFactory.GetCurrentSession(). See Contextual Sessions in the NHibernate reference.
Alternatively, you can manage the sessions using whatever you like, but then you must use that mechanism to retrieve the current session and not expect NHibernate to know about it.

ServiceStack self-hosted application with per-request lifetime scope

Working with ServiceStack I've stuck with the problem of objects lifetime management in self-hosted web application.
My requirements:
Need of per-request objects lifetime scope.
I'm using Castle Windsor IoC with implemented ServiceStack IoC adapter.
My application is self-hosted with base class AppHostHttpListenerPoolBase (ServiceStack v4)
Probably one day I want to move on IIS, thus it's must be flexible.
General problem:
Castle Windsor IoC implements its own per-request lifetime strategy but it is binded to http modules, thus it works only with IIS hosted apps. Hence, I have to implement my custom IScopeAccessor (provided by Castle Windsor) to handle objects lifetime. The problem here is in absence of hooks which I can use to bind to current request.
Given
public class MyScopeAccessor : IScopeAccessor
{
public ILifetimeScope GetScope(CreationContext context)
{
//implement it
}
}
I have to implement GetScope method.
There are two main ideas I cannot complete:
Using of [Threadstatic]
In MyScopeAccessor I just store
[ThreadStatic]
private static ILifetimeScope _currentLifetimeScope;
and create new scope after first GetScope if it's not initialzied yet.
Problems:
Hard to dispose. Best way to dispose _currentLifetimeScope is to implement custom IServiceRunner (or inherit from ServiceRunner) overriding AfterEachRequest method. But I don't exactly know if AfterEachRequest is actually executed in request thread.
Moving to IIS can cause some problems because as I know IIS doesn't guarantee unchangeable binding between theads and request contexts.
Using of IRequest instance
In MyScopeAccessor I just store
private static readonly ConcurrentDictionary<IRequest, ILifetimeScope> LifetimeScopes;
and create and dispose current lifetime scope in corresponding custom ServiceRunner methods (OnBeforeEachRequest, OnAfterEachRequest).
Problems:
I don't know how to get access to current request globally from GetScope, MyScopeAccessor knows nothing about services and requests.
Also, it is interesting if ServiceStack default Funq IoC solves this problem.
Funq does handle RequestScoped dependencies which stores Request Context dependencies in the RequestContext.Instance.Items[] dictionary.
Any disposables can be registered in RequestContext.Instance.TrackDisposable() are automatically disposed of at the end of the request.
At the end of each request AppHost.OnEndRequest() is fired which goes through and releases any dependencies stored in the RequestContext for that request.
If your Windsor ContainerAdapter implements the IRelease interface it's automatically called to release any instances which can be handled itself. Both these API's are overridable in your AppHost if you want to change the default behavior:
public virtual void OnEndRequest()
{
var disposables = RequestContext.Instance.Items.Values;
foreach (var item in disposables)
{
Release(item);
}
RequestContext.Instance.EndRequest();
}
public virtual void Release(object instance)
{
try
{
var iocAdapterReleases = Container.Adapter as IRelease;
if (iocAdapterReleases != null)
{
iocAdapterReleases.Release(instance);
}
else
{
var disposable = instance as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
catch { /*ignore*/ }
}

Should I dispose a service (layer)-class after I'm done using it?

So I have a service layer in my project which contains all the business logic. It is an MVC project, so when a user calls a page that requires some logic, the service class is instantiated and then used (from the controller). But it will not be used again since a new request will just instantiate a new object again.
Should I dispose these service classes after using them(using a 'using' statement? Or won't I gain any benefit from it since the garbage collector will come not much later anyway?
If this is the case, the same will apply for using my repository objects I guess.
Depends on what kind of resources your service layer are using.
A general rule of thumb:
If anything uses something which implements IDisposable then anything should either implement IDisposable or call Dispose() when done with the something
Why? Let's say that the service layer uses database connections. If you don't dispose them, they will remain open until the garbage collector collects them, leading to a lot of idle connections. That also means that the ADO.NET connection pool have to create new connections for every new HTTP request instead of reusing old ones (when the pool eventually gets empty).
Making sure that IDisposables are disposed is a cheap way of using resources efficiently.
So if you got something like this:
public class MyService
{
public MyRepository _repos = new MyRepository();
// [...]
}
public class MyRepository
{
public SqlConnection _connection = new SqlConnection("...");
// [...]
}
You should start by changing your repos to IDisposable
public class MyRepository : IDisposable
{
public SqlConnection _connection = new SqlConnection("...");
// [...]
public void Dipose()
{
_connection.Dispose();
}
}
Now if we want to follow the rule we either have to dispose the repository inside the methods that use the repos, or implement IDisposable in the service class too. We do the latter since we don't really now when the invoker has finished calling us (the invoker might call two methods in the service).
public class MyService : IDisposable
{
public MyRepository _repos = new MyRepository();
// [...]
public void Dipose()
{
_repos.Dispose();
}
}
finally we can now just do this in the controller to get everything disposed:
public ActionResult Execute()
{
using (var service = new MyService())
{
service.CallA();
service.CallB();
}
}
I do recommend that you follow the Dispose pattern

WCF: Is it safe to override the Client's Dispose method using a partial class?

I'd like to override the Dispose method of generated proxy (ClientBase) because of the fact that disposing of a proxy calls Close and can throw an exception when the channel is faulted.
The only way I came up was to create a partial class to my generated proxy, make it inherit from IDisposable:
public partial class MyServiceProxy : IDisposable
{
#region IDisposable Members
public void Dispose()
{
if (State != System.ServiceModel.CommunicationState.Faulted)
Close();
else
Abort();
}
#endregion
}
I did some test and my Dispose method is indeed called.
Do you see any issue with this strategy?
Also, I don't like the fact that I'll have to create this partial class for every generated proxy.
It be nice if I was able to make my proxy inherit from a base class...
There's no issue with it. Customizing designer-generated code in this fashion is exactly the feature that partial classes are intended to provide, and this is one of the recommended ways of dealing with the broken IDisposable implementation on ClientBase.
As for having to re-implement this code for every WCF client - unfortunately, yes, you will, if you want to use the IDisposable pattern with these. You could extract the if/else block into a utility method but you would still have to create a partial class for each one and override Dispose.
Seeing as how the above is rather tedious to do, many people choose to use the Service Proxy Helper instead, since it doesn't require writing any new code.
I use a slightly modified version, myself:
public static class Service<TProxy>
where TProxy : ICommunicationObject, IDisposable, new()
{
public static void Using(Action<TProxy> action)
{
TProxy proxy = new TProxy();
bool success = false;
try
{
action(proxy);
proxy.Close();
success = true;
}
finally
{
if (!success)
{
proxy.Abort();
}
}
}
}
Which allows writing this kind of code:
Service<MyServiceClient>.Using(svc => svc.PerformOperation());
Or:
Service<MyServiceClient>.Using(svc =>
{
var result = svc.PerformOperation();
ProcessResult(result);
});
Note: WCF proxies are expensive to create, so you generally want to try to keep them alive as long as possible instead of creating and disposing them every few seconds (or more). This is intended for clients that are infrequently-used.
Overriding the Dispose() method is a perfectly valid strategy.
There are a few other options in the answers to this question: What is the best workaround for the WCF client `using` block issue?

Categories

Resources