I've posted a general guideline question when it comes to IDisposable objects and using Autofac here: Dependency Injection and IDisposable. Unfortunately, I did not account for one particular scenario in our project and it's really a separate question that stands on its own, so will ask it here:
I have a Repository object that manages the life of a session object inside it. Thus, Repository object is IDisposable and destroys session (Repository is injected with a factory delegate at construction, instantiates session during first usage, and destroys session in IDisposable if session is not null). Per reference to StackOverflow question above, I understand that any object that is injected with my Repository object should not be implementing IDisposable since Autofac will handle disposing of my repositories, if it is injecting them.
Per mentioned StackOverflow thread, I've started cleaning up IDisposable usage from my objects until I stumbled upon NotificationPublisher class shown below. There are a few places like it where classes are injected with implementation of IComponentContext that acts as a factory. Resolution happens manually in a function, because the codebase does not know what handler needs to be injected until the runtime.
public class NotificationPublisher : INotificationPublisher
{
private readonly IComponentContext _container;
private readonly INotificationManager _notificationManager;
public NotificationPublisher(IComponentContext container,
INotificationManager notificationManager)
{
_container = container;
_notificationManager = notificationManager;
}
public IEnumerable<IAlertSubscription> Publish(Account account,
INotificationInitiator owner, INotificationEntity entity,
Int32 severity, CheckCycleContext monitoringContext)
{
var alertSubscriptions =
_notificationManager.GetAlertSubscriptions(account, owner, severity);
foreach (var alertSubscription in alertSubscriptions)
{
var destination = alertSubscription.GetConsumer();
Type handlerType = typeof (INotificationHandler<,>)
.MakeGenericType(entity.GetType(), destination.GetType());
using (var handler =
(INotificationCustomHandler)_container.ResolveOptional(handlerType))
{
if (handler == null) continue;
try
{
Retry.Execute(() => (handler).Send(entity, destination), 3, 500);
monitoringContext.Record(CheckCycleContext.CycleSeverity.Information,
string.Format("NotificationPublisher.Publish:{0}/{1}",
entity.GetType().Name, destination.GetType().Name), "Success");
}
catch (Exception ex)
{
monitoringContext.Record(CheckCycleContext.CycleSeverity.Error,
string.Format("NotificationPublisher.Publish:{0}/{1}",
entity.GetType().Name, destination.GetType().Name), ex.Message, ex,
new {entity, destination});
}
}
}
return alertSubscriptions;
}
}
I'm assuming that since INotificationCustomHandler is manually resolved, it must be manually disposed with the using statement, becuase implementations of INotificationCustomHandler are injected with implementations of IManager that is injected with implementations of IRepository.
Thus, in this situation I need to propagate IDisposable throughout my codebase which goes against what I was suggested in the prior SO question.
How do I manually resolve objects via factories when needed and yet let Autofac handle disposing?