I am writing a service that tells multiple classes implementing the interface IDeviceFinder to go look for connected devices, which the service will put in a cache for other objects to use.
The controller script looks as follows:
private Container _container;
public bool Start()
{
_container.Collection.Register<IDeviceFinder>(
new Assembly[] { Assembly.GetExecutingAssembly() });
_container.Register<IDeviceCache, DeviceCache>(Lifestyle.Singleton);
_container.Register<IDeviceService, DeviceService>();
_container.Verify();
}
Using Simple Injector, the device finders are passed to the DeviceService in the constructor. When the finders find a device they report it back to the service via a delegate. The service then proceeds to put it into the device cache (a singleton).
The device service itself implements the interface IDisposable. Using Dispose the service unsubscribes from the delegates of the device finders.
public class DeviceService : IDeviceService //IDeviceService inherits from IDisposable
{
private IDeviceCache _cache;
private List<IDeviceFinder> _finders = new List<IDeviceFinder>();
public DeviceService(IDeviceCache cache, IDeviceFinder[] finders)
{
this._cache = cache;
this._finders = finders.ToList();
foreach (var finder in this._finders)
{
finder.DeviceFound += AddDeviceToCache;
}
}
public void Dispose()
{
foreach (var finder in this._finders)
{
finder.DeviceFound -= AddDeviceToCache;
}
}
private void AddDeviceToCache(Device device)
{
//...
}
}
However, Simple Injector gives me a warning that the transient DeviceService cannot implement IDisposable.
When I change the lifestyle to be scoped, I get a warning that there is a lifestyle mismatch, because DeviceService (async scoped) depends on IDeviceFinder[] (transient).
How would I fix this error? I don't really want to get rid of the IDisposable interface.
Related
I have a number of services that ultimately depend on the request context but, as they are expensive to instantiate, I'd like to register them with Reuse.Singleton. That means I need to inject these singletons with some form of proxies of my scoped services.
I found that I can register a scoped service A normally and then inject it as Func<A>, allowing me to manually resolve A by invoking the injected delegate, i.e.
// DryIoC config
private static ConfigureDI(...)
{
...
c.Register<A>(Reuse.InWebRequest);
c.Register<B>(Reuse.Singleton);
...
}
// Scoped service
public class A
{
public object Foo() { ... }
}
// Singleton service
public class B
{
private readonly Func<A> _a;
public object Bar()
{
return _a().Foo();
}
}
This approach seems to work, but I wonder: is there a way to do this without having to modify the original classes?
Im trying to figure out how to dynamically instantiate class when it's first used. Something like autofac's Lazy does but without refactoring all my classes.
Is there any possiblity to do something like this:
public class MyService : IMyService {
public MyService() {
// I want it to be invoked only if SomeMethod was invoked before.
// 1. Attempt to invoke SomeMethod
// 2. call MyService.constructor
// 3. invoke MyService.SomeMethod()
}
public void SomeMethod() {
///literally any code.
}
}
It has to be done without changing existing codebase (except services registration/ autofac setup or other areas that could be changed without much effort), and all services look's like that:
public class Service : IService {
public Service(AnotherService service){
///...
}
}
My initial idea was to create Proxy class and then while registering services wrap it with that proxy.
It could look something like this:
public class Proxy<T>
{
private T _target;
private bool instantiated = false;
private void Instantiate()
{
Console.WriteLine("Creating instance");
_target = Activator.CreateInstance<T>();
}
public void xxx() - this method should be called every time any wrapped type method get's called.
{
if (instantiated == false)
{
Instantiate();
instantiated = true;
}
/// proceed with invocation. (im not sure how to do this via reflection).
}
}
The main issue with this idea is that above proxy class should be created at runtime via reflection and it has to mimic wrapping class behaviour.
I'd appreciate any advice on how to approach this problem.
All i want to lazy create dependencies in autofac container (currently if dependency A is requiring dependency B then B is instantiated, i want change this to instantiate B only if any method from A calls B.method).
Thanks!
What you're looking for is the Proxy pattern. You can create a lazy proxy as follows:
public class LazyMyServiceProxy : IMyService
{
private readonly Lazy<MyService> lazy;
public LazyMyServiceProxy(Lazy<MyService> lazy) => this.lazy = lazy;
public void SomeMethod() => this.lazy.SomeMethod();
}
You can use this proxy using the following Autofac registrations.
builder.RegisterType<MyService>();
builder.RegisterType<LazyMyServiceProxy>().As<IMyService>();
My application creates IDisposable objects that should be reused, so I create a factory that encapsulates the creation and reuse of those objects, code like this:
public class ServiceClientFactory
{
private static readonly object SyncRoot = new object();
private static readonly Dictionary<string, ServiceClient> Clients = new Dictionary<string, ServiceClient>(StringComparer.OrdinalIgnoreCase);
public static ServiceClient CreateServiceClient(string host)
{
lock(SyncRoot)
{
if (Clients.ContainsKey(host) == false)
{
Clients[host] = new ServiceClient(host);
}
return Clients[host];
}
}
}
public class QueryExecutor
{
private readonly ServiceClient serviceClient;
public QueryExecutor(string host)
{
this.serviceClient = ServiceClientFactory.CreateServiceClient(host);
}
public IDataReader ExecuteQuery(string query)
{
this.serviceClient.Query(query, ...);
}
}
What makes me scratch my head is, ServiceClient is IDisposable, I should dispose them explicitly sometime.
One way is implementing IDisposable in QueryExecutor and dispose ServiceClient when QueryExecutor is disposed, but in this way, (1) when disposing ServiceClient, also needs to notify ServiceClientFactory, (2) cannot reuse ServiceClient instance.
So I think it would be much easier to let ServiceClientFactory manage lifetime of all ServiceClient instances, if I go this way, what is the best practice here to dispose all IDisposable objects created by factory? Hook the AppDomain exit event and manually call Dispose() on every ServiceClient instance?
A couple of things to think about here...
Firstly, what you appear to be describing is some variation of the Flyweight pattern. You have an expensive object, ServiceClient, which you want to reuse, but you want to allow consumer objects to create and destroy at will without breaking the expensive object. Flyweight traditionally does this with reference-counting, which might be a bit old hat.
You'll need to make sure that consumers cannot dispose the ServiceClient directly, so you'll also need a lightweight Facade which intercepts the calls to ServiceClient.Dispose and chooses whether to dispose the real object or not. You should hide the real ServiceClient from consumers.
If all that is feasible, you could rewrite your approach as something like:
// this is the facade that you will work from, instead of ServiceClient
public interface IMyServiceClient : IDisposable
{
void Query(string query);
}
// This is your factory, reworked to provide flyweight instances
// of IMyServiceClient, instead of the real ServiceClient
public class ServiceClientFactory : IDisposable
{
// This is the concrete implementation of IMyServiceClient
// that the factory will create and you can pass around; it
// provides both the reference count and facade implementation
// and is nested inside the factory to indicate that consumers
// should not alter these (and cannot without reflecting on
// non-publics)
private class CachedServiceClient : IMyServiceClient
{
internal ServiceClient _realServiceClient;
internal int _referenceCount;
#region Facade wrapper methods around real ServiceClient ones
void IMyServiceClient.Query(string query)
{
_realServiceClient.Query(query);
}
#endregion
#region IDisposable for the client facade
private bool _isClientDisposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_isClientDisposed)
{
if (Interlocked.Decrement(ref _referenceCount) == 0)
{
// if there are no more references, we really
// dispose the real object
using (_realServiceClient) { /*NOOP*/ }
}
_isClientDisposed = true;
}
}
~CachedServiceClient() { Dispose(false); }
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
// The object cache; note that it is not static
private readonly ConcurrentDictionary<string, CachedServiceClient> _cache
= new ConcurrentDictionary<string, CachedServiceClient>();
// The method which allows consumers to create the client; note
// that it returns the facade interface, rather than the concrete
// class, so as to hide the implementation details
public IMyServiceClient CreateServiceClient(string host)
{
var cached = _cache.GetOrAdd(
host,
k => new CachedServiceClient()
);
if (Interlocked.Increment(ref cached._referenceCount) == 1)
{
cached._realServiceClient = new ServiceClient(host);
}
return cached;
}
#region IDisposable for the factory (will forcibly clean up all cached items)
private bool _isFactoryDisposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_isFactoryDisposed)
{
Debug.WriteLine($"ServiceClientFactory #{GetHashCode()} disposing cache");
if (disposing)
{
foreach (var element in _cache)
{
element.Value._referenceCount = 0;
using (element.Value._realServiceClient) { }
}
}
_cache.Clear();
_isFactoryDisposed = true;
}
}
~ServiceClientFactory() { Dispose(false); }
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
// This is just an example `ServiceClient` which uses the default
// implementation of GetHashCode to "prove" that new objects aren't
// created unnecessarily; note it does not implement `IMyServiceClient`
public class ServiceClient : IDisposable
{
private readonly string _host;
public ServiceClient(string host)
{
_host = host;
Debug.WriteLine($"ServiceClient #{GetHashCode()} was created for {_host}");
}
public void Query(string query)
{
Debug.WriteLine($"ServiceClient #{GetHashCode()} asked '{query}' to {_host}");
}
public void Dispose()
{
Debug.WriteLine($"ServiceClient #{GetHashCode()} for {_host} was disposed");
GC.SuppressFinalize(this);
}
}
Secondly, in general, I'd remove the static clauses from the factory and make ServiceClientFactory : IDisposable. You'll see I've done that in my example above.
It may seem like you're just pushing the problem up the chain, but doing so allows you to make this decision on a case-by-case basis, per-something (application, session, request, unit test run -- whatever makes sense) and have the object that represents your something be responsible for the disposal.
If your application would benefit from a single-instance cache then expose a singleton instance as part of an AppContext class (for example) and call AppContext.DefaultServiceClientFactory.Dispose() in your clean-shutdown routine.
The emphasis here is on a clean shutdown. As others have stated, there is no guarantee that your Dispose method will ever actually be called (think power-cycling the machine, mid-run). As such, ideally, ServiceClient.Dispose would not have any tangible side-effects (i.e. beyond freeing resources that would be freed naturally if the process terminates or the machine power-cycles).
If ServiceClient.Dispose does have tangible side-effects, then you have identified a risk here, and you should clearly document how to recover your system from an "unclean" shutdown, in an accompanying user manual.
Thirdly, if both ServiceClient and QueryExecutor objects are intended to be reusable, then let the consumer be responsible for both the creation and disposal.
QueryExecutor only really has to be IDisposable in your sample because it can own a ServiceClient (which is also IDisposable). If QueryExecutor didn't actually create the ServiceClient, it wouldn't be responsible for destroying it.
Instead, have the constructor take a ServiceClient parameter (or, using my rewrite, an IMyServiceClient parameter) instead of a string, so the immediate consumer can be responsible for the lifetime of all objects:
using (var client = AppContext.DefaultServiceClientFactory.CreateServiceClient("localhost"))
{
var query = new QueryExecutor(client);
using (var reader = query.ExecuteReader("SELECT * FROM foo"))
{
//...
}
}
PS: Is there any need for consumers to actually directly access ServiceClient or are there any other objects which need a reference to it? If not, perhaps reduce the chain a little and move this stuff directly to QueryExecutor, i.e. using a QueryExecutorFactory to create flyweight QueryExector objects around cached ServiceClient instances, instead.
Static classes are tricky that way. The constructor for a static class is invoked when an instance member is first invoked. The class is destroyed if and when the application domain is destroyed. If the application terminates abruptly (aborts), there's no guarantee a constructor/finalizer would be called.
Your best bet here is to redesign the class to use a singleton pattern. There are ways to work around this issue, but they require strange, dark magic forces that may cost you your soul.
EDIT: As servy points out, a Singleton won't help here. A destructor is a finalizer, and you won't have any guarantee that it will be called (for a wide variety of reasons). If it were me, I'd simply refactor it to an instantiable class that implements IDisposable, and let the caller deal with calling Dispose. Not ideal, I know, but it's the only way to be sure.
This question is more of a "how do I do it?", rather than a "what am I doing wrong?". I have a class which is called QueryProcessor that processes queries (think CQRS). That object is injected into my presenters. The QueryProcessor needs to use the kernel to resolve bindings. Injecting the kernel in, either directly or via a factory, is easy. Doing so without causing a memory leak is the trick.
I have verified using a memory profiler that none of my QueryProcessor objects are being garbage collected. The class looks like this:
public sealed class QueryProcessor : IQueryProcessor, IDisposable
{
private readonly IKernelFactory _container;
private bool _disposed;
public QueryProcessor(IKernelFactory container)
{
_container = container;
}
//[DebuggerStepThrough]
public TResult Process<TResult>(IQuery<TResult> query)
{
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _container.RetrieveKernel().Get(handlerType);
return handler.Handle((dynamic)query);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing && !_disposed)
{
// dispose of stuff here
_disposed = true;
}
}
}
public interface IKernelFactory
{
IKernel RetrieveKernel();
}
My composition root is reasonably straightforward. I am using the factory extension of Ninject.
public void OnLoad(IKernel kernel)
{
// Auto-Register all the validators which are stored in the Service assembly.
AssemblyScanner.FindValidatorsInAssembly(_serviceAssembly).ForEach(
result => kernel.Bind(result.InterfaceType, result.ValidatorType)
);
ManualRegistrations(kernel);
kernel.Bind<IKernelFactory>().ToFactory();
AutoRegisterType(kernel, typeof(IQueryHandler<,>));
AutoRegisterType(kernel, typeof(ICommandHandler<>));
}
As mentioned, the injection is working, but it is leaving a memory leak. How am I supposed to get the Ninject kernel resolving stuff in my QueryProcessor without causing the leak?
Thanks
Update - New Problem
I tried to solve this problem by creating a new kernel with a new module, separate from the main kernel of the Composition Root. These sub-kernels would be created and disposed up, with their lifetimes being tied to that of the QueryProcessors. I hooked it up like this in the main module:
kernel.Bind<IQueryProcessor>().ToMethod(ctx => new QueryProcessor(new StandardKernel(new ProcessorModule(_serviceAssembly)))).InTransientScope();
It works fine before the kernel is disposed of for the first time. But after that, I get the following error message:
Error loading Ninject component ICache
No such component has been registered in the kernel's component container.
Suggestions:
1) If you have created a custom subclass for KernelBase, ensure that you have properly
implemented the AddComponents() method.
2) Ensure that you have not removed the component from the container via a call to RemoveAll().
3) Ensure you have not accidentally created more than one kernel.
Damned if I do, damned if I don't ...
Since your application, not the DI container, is creating the instance it is also responsible for disposing the instance. This scenario can be handled by using the Register, Resolve, and Release pattern.
If you inject the kernel, then you have effectively implemented the service locator anti-pattern. This means your application is explicitly dependent on your DI framework.
Rather than injecting the kernel, you should use an abstract factory as mentioned in the post DI Friendly Framework to handle both creating and releasing the handler instances.
public interface IHandlerFactory
{
dynamic Create(Type handlerType);
void Release(dynamic handler);
}
public interface HandlerFactory
{
private readonly Func<Type, dynamic> handlerMethod;
public HandlerFactory(Func<Type, dynamic> handlerMethod)
{
if (handlerMethod == null)
throw new ArgumentNullException("handlerMethod");
this.handlerMethod = handlerMethod;
}
public dynamic Create(Type handlerType)
{
return handlerMethod(handlerType);
}
public void Release(dynamic handler)
{
IDisposable disposable = handler as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
Usage
public sealed class QueryProcessor : IQueryProcessor
{
private readonly IHandlerFactory handlerFactory;
public QueryProcessor(IHandlerFactory handlerFactory)
{
if (handlerFactory == null)
throw new ArgumentNullException("handlerFactory");
this.handlerFactory = handlerFactory;
}
//[DebuggerStepThrough]
public TResult Process<TResult>(IQuery<TResult> query)
{
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = this.handlerFactory.Create(handlerType);
try
{
return handler.Handle((dynamic)query);
}
finally
{
this.handlerFactory.Release(handler);
}
}
}
Note that if you use this approach, you are not requiring every handler to implement IDisposable, nor does your QueryProcessor unnecessarily need to implement IDisposable.
In your composition root, you just need to implement the handler method and register it as a parameter to your factory.
Func<Type, dynamic> handlerMethod = type => (dynamic)kernel.Resolve(type);
kernel.Bind<IHandlerFactory>().To<HandlerFactory>()
.WithConstructorArgument("handlerMethod", handlerMethod);
Of course, if you are processing your handlers asynchronously you have to keep the instance alive until the end of the request rather than disposing it as soon as the handler.Handle() method returns. If that is the case, I suggest you analyze the source code for WebApi to work out what pattern is used to do that when dealing with the System.Web.Http.ApiController.
Suppose that your code is properly designed for DI and IOC through constructor injection of any dependencies. Then whether an IOC container or DI-by-hand is used or not at the composition root doesn't matter much for this problem. I think.
Anyway, I find myself over and over again in a mental struggle with how I should best deal with scope-based services, like transactions or other obviously transient operations. There are constraints that I want to abide to:
Don't let dependency interfaces be IDisposable - it's a leaky abstraction that only the actual implementing type (and the fiddler sitting at the composition root) should care about.
Don't use static service locator types deep down the graph to resolve a dependency - only inject and resolve through the constructor.
Don't pass the IOC container, if any, as a dependency down the graph.
To be able to use using, we need IDisposable, but since a dependency interface shouldn't be IDisposable, how do you get around it to get scoped behavior?
In cases like this I would inject a service factory that creates those scoped services and let the service interface derive from IDisposable. This way the factory would be responsible to create the appropriate service instances and the only point that decides which service implementation to return. You would not need to inject the scoped service anywhere.
public interface ITransaction : IDisposable
{
}
public interface ITransactionFactory
{
ITransaction CreateTransaction();
}
public class Foo
{
private readonly ITransactionFactory transactionFactory;
public Foo(ITransactionFactory transactionFactory)
{
this.transactionFactory = transactionFactory;
}
public void DoSomethingWithinTransaction()
{
using(ITransaction transaction = this.transactionFactory.CreateTransaction())
{
DoSomething();
}
}
}
Most IoC containers today have substantial built-in support for units of work of this nature.
In Autofac, the mechanism that best fits your requirements is the Owned<T> relationship type. You can see it in action (and get some more material) via this article.
Hope this helps,
Nick
Roll your own "garbage collector" maybe? Something that periodically checks IsComplete and/or an LastAccessed attribute of a Dictionary<Transaction> and wastes the "old" ones. It's "a walking memory leak" but either you clean-up explicitly (like through IDisposable) or you workout how to clean-up automatically.
There may be an AOP solution to kicking-off the "gc"... a commit/rollback sounds like a good place to cut... and maybe you won't even need a GC at all... just cleanup the transaction on the way back-up the callstack from commit or rollback.
Good luck with it. I'll be interested to see what solutions (and ideas) other people come-up with.
Cheers. Keith.
I guess another alternative you could use is to wrap your instances with a disposable type, that way it could automatically handle the disposal of the type regardless of whether the type is actually disposable. E.g, I could define something like:
public class DisposableWrapper<T> : IDisposable
{
private readonly T _instance;
private readonly IDisposable _disposable;
public DisposableWrapper(T instance)
{
_instance = instance;
_disposable = instance as IDisposable;
}
public void Dispose()
{
if (_disposable != null)
_disposable.Dispose();
}
public static implicit operator T(DisposableWrapper<T> disposableWrapper)
{
return disposableWrapper._instance;
}
}
(Hopefully with a bit more error handling!)
Given that I know at the point of disposal whether the type is disposable, I can call it accordingly. I can also provide an implicit operator to cast back to the inner type from it. With the above, and a nifty extension method:
public static class DisposableExtensions
{
public static DisposableWrapper<T> Wrap<T>(this T instance)
{
return new DisposableWrapper<T>(instance);
}
}
Let's imagine that I have a service I am injecting into a type, it could be:
public interface IUserService
{
IUser GetUser();
}
I could potentially do something like:
public HomeController(IUserService service)
{
using (var disposable = service.Wrap())
{
var user = service.GetUser();
// I can even grab it again, implicitly.
IUserService service2 = disposable;
}
}
Now regardless of whether that concrete implementation of IUserService is disposable or not, I can still safely work on the assumption that it doesn't matter.
Another quick console example:
class Program
{
static void Main(string[] args)
{
using (var instance = new ClassA().Wrap())
{
ClassA instanceA = instance;
}
using (var instance = new ClassB().Wrap())
{
ClassB instanceB = instance;
}
Console.ReadKey();
}
}
public class ClassA
{
}
public class ClassB : IDisposable
{
public void Dispose()
{
Console.Write("Disposed");
}
}