Castle windsor is used in MVC application as it is described here:
Plugging Windsor in MVC
In my application there is one difference and that is method AddControllerLoggingFunctionality:
var controller = ((IController)container.Kernel.Resolve(controllerType)).AddControllerLoggingFunctionality();
This method is in logger class:
[DebuggerStepThrough]
public static class Logger
{
private static readonly Castle.DynamicProxy.ProxyGenerator proxyGenerator;
static Logger()
{
proxyGenerator = new Castle.DynamicProxy.ProxyGenerator();
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(
typeof(ServiceContractAttribute));
}
public static TInterface AddControllerLoggingFunctionality<TInterface>(this TInterface implementation)
where TInterface : class
{
if (implementation == null)
{
throw new ArgumentNullException("implementation");
}
if (!typeof(TInterface).IsInterface)
{
throw new Exception("Type of 'TInterface' must be interface.");
}
Castle.DynamicProxy.ProxyGenerationOptions options =
new Castle.DynamicProxy.ProxyGenerationOptions();
var origAttribs = implementation.GetType().GetCustomAttributesData();
if (origAttribs != null)
{
foreach (var origAttrib in origAttribs)
{
options.AdditionalAttributes.Add(
AttributeUtil.CreateBuilder(origAttrib));
}
}
return (TInterface)proxyGenerator.CreateInterfaceProxyWithTarget<TInterface>(
implementation,
options,
new ControllerLoggingInterceptor(implementation.GetType()));
}
}
And
Can someone explain this? Why IController can call AddControllerLoggingFunctionality and what does it?
Because of this change, this controllers are never released from memory(when
container.Kernel.ReleaseComponent(controller); is called) and I get memory leak.
The "Object tracked by release policy" counter increase all the time.
If i remove AddControllerLoggingFunctionality, then "Object tracked by release policy" counter decrease each time when I call ReleaseComponent and memory leak doesn't happen.
You aren't call Release() on the controller but are calling it on the proxy you manually created so Release() is just a no-op to Windsor as it doesn't know about that object and so keeps tracking the controller component.
If you use Windsor's built-in interception support you don't have to worry about this problem as Windsor will know how to dispose of the component when passed its own internally managed proxy.
If you want to test this before changing to Windsor's built-in support, cast your proxy to Castle.DynamicProxy.IProxyTargetAccessor and call DynProxyGetTarget() to get your controller instance which you'll need to pass to Release().
(This answer is copied from our discussion on the Castle Users mailing list)
Related
I would like to implement an application-wide container and a (nested) one for each project created by the user. I looked into Owned<T>, but then - as far as I could figure it out - my internal collection of projects would have to be <Owned<Project>> which I do not want and also I failed to inject a project dependency into objects used within the project scope ("circular component dependency"). I considered using a new ContainerBuilder within the project factory, but then the "nested" aspect is missing.
A few exapmles of classes (with the dependencies) I would like to have:
In a global scope: ProjectManager(IProjectFactory)
In each project's scope: Project(IDocumentFactory documentFactory), Document(IProject project, IProjectSettings settings).
So for the project's scope I would register IDocumentFactory, IProjectSettings (and the project itself?).
When a project is closed/disposed all created dependencies should, of course, also be disposed.
If possible, the concrete classes (except for the ProjectFactory) should be Autofac-agnostic.
FYI: The application is a desktop application using C# and Autofac 4.8.
Thanks!
UPDATE: Thanks for your comments, the discussion helped me find my own opinion. Currently I'm settling for something like this in my ProjectFactory:
public Project Create()
{
var scope = _globalScope.BeginLifetimeScope(MyIocHelper.RegisterProjectDependencies);
var p = scope.Resolve<Project>();
_projectScopes.Add(p, scope);
p.Disposing += project_Disposing;
return p;
}
Things to note:
As far as I can tell, using a tag for the lifetime scope is not necessary.
Project raises a Disposing event when its Dispose method is called the first time.
The factory keeps a Dictionary<Project, ILifetimeScope> and cleans it up when the project is disposed.
You can accomplish what you are looking for with a combination of named lifetime scopes and instance-per-lifetime-scope registrations.
Documentation here: http://autofac.readthedocs.io/en/latest/lifetime/working-with-scopes.html#tagging-a-lifetime-scope
You need to:
register your ProjectManager as SingleInstance
register Project as this:
builder.Register<Project>()
.As<IProject>()
.InstancePerMatchingLifetimeScope("project");
This will guarantee that a Project can be resolved (e.g. by a Document) once per each scope tagged as "project".
Implement an OpenProject (or something along) method in ProjectManager. This method should instantiate a LifetimeScope tagged as "project", register in it the IDocumentFactory, IProjectSettings, so they are resolved only once for each project scope, and attach the scope itself onto the Project instance. This is crucial: you need the scope to be disposed when you dispose the project.
public class ProjectManager : IProjectFactory
{
private readonly ILifetimeScope _scope;
public ProjectManager(ILifetimeScope scope)
{
// this is going to be the global scope.
_scope = scope;
}
public Project OpenProject(IDocumentFactory docFactory, IProjectSettings settings)
{
var projectScope = _scope.BeginLifetimeScope("project");
projectScope.RegisterInstance(docFactory).AsImplementedInterfaces();
projectScope.RegisterInstance(settings).AsImplementedInterfaces();
return projectScope.Resolve<Project>();
}
}
public class ProjectScope : IDisposable
{
private readonly ILifetimeScope _scope;
public ProjectManager(ILifetimeScope scope)
{
// this is going to be the project scope.
_scope = scope;
}
public void Dispose() {
if (_scope != null) {
_scope.Dispose();
_scope = null;
}
}
}
public class Project : IDisposable
{
private readonly ProjectScope _scope;
public Project(ProjectScope scope /*, ...*/)
{
_scope = scope;
}
public void Dispose() {
// pay attention that this method will be called 2 times, once by you
// and another time by the underlying LifetimeScope. So this code should
// handle that gracefully (so the _scope == null).
if (_scope != null) {
_scope.Dispose();
_scope = null;
}
}
}
Given all this, you keep every using Autofac out of every class, with the 2 exceptions of the global manager and the ProjectScope. You can change some bits on how the scope is handled, if you accept a single using Autofac in the Project class itself: you can get directly the ILifetimeScope and dispose of it directly.
Hope this helps!
I am using WebAPI with Autofac and starting a long running task (fire and forget stuff) which will be alive after the lifetime of HTTP request. Therefore, I would like to prevent the ApiController to automatically dispose the object which consists the long running task, after ApiController lifetime ends.
In the Web API controller I would like to use Owned<T> class in order to inject one of the dependencies without binding it to the LifeTimeScope of the ApiController instance. It seems Owned<T> is a good choice for that, but I would like inherit from it in order to have virtual (polymorphic) Value property which I can mock with the Moq library.
However, when I inherit from Owned<T> autofac does not recognize (due to the reflection?) my MyOwned<T> and throws the exception below.
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'autofak.Meta' can be invoked with the available services and parameters: Cannot resolve parameter 'System.Func'2[System.Int32,autofak.MyOwned'1[autofak.Root]] root' of constructor 'Void .ctor(System.Func'2[System.Int32,autofak.MyOwned'1[autofak.Root]])'.
This is my top-level class which depends on Root class.
class Meta
{
public MyOwned<Root> Root { get; private set; }
public Meta(Func<int, MyOwned<Root>> root)
{
Root = root(2);
}
}
My registration code is below:
var container = new ContainerBuilder();
container.RegisterType<child>();
container.RegisterType<grandchild>();
container.RegisterType<Root>();
container.RegisterType<Meta>();
var builder = container.Build();
Is it possible to inherit from Owned and make it work or should I try a different approach?
Update:
Besides the accepted solution, I also followed a different path by creating a SingleInstance() factory in order to create new LifeTimeScope objects from the root/application lifetimescope. Similar to Owned<T> class I created a new class which also stores this new lifetime (created from root lifetime scope) for each task and makes it possible to call Dispose() as in the Owned<T>.
The easiest way to do what you want would be to create a new component that uses a Owned<T> instead of inheriting from Owned<T>
public interface IOwned<T> : IDisposable
{
T Value { get; }
}
public class MyOwned<T> : IOwned<T>
{
public MyOwned(Owned<T> owned)
{
this._owned = owned;
}
private readonly Owned<T> _owned;
public virtual T Value
{
get
{
return this._owned.Value;
}
}
public void Dispose()
{
this._owned.Dispose();
}
}
Then register your component using the RegisterGeneric method and ExternallyOwned.
builder.RegisterGeneric(typeof(MyOwned<>))
.As(typeof(IOwned<>))
.ExternallyOwned();
You need to declare it as ExternallyOwned because without this Autofac will try to dispose this component at the end of its ILifetimeScope and the goal of Owned<T> is to let you decide when you dispose the component.
Another option would be to create your own Owned<T> component which is a lot more complex because you will need to implement IRegistrationSource to manage the child ILifetimeScope created by the Owned<T> component.
Attempting to inject data into a FluentValidation validator:
public class MyFormValidator : AbstractValidator<MyForm>
{
private readonly IQueryable<Models.User> _users;
public MyFormValidator(IQueryable<Models.User> users)
{
_users = users;
...
}
}
My validator factory:
public class DependencyResolverValidatorFactory : ValidatorFactoryBase
{
private readonly IContainer container;
public DependencyResolverValidatorFactory(IContainer container)
{
this.container = container;
}
public override IValidator CreateInstance(Type validatorType)
{
return container.ResolveOptionalKeyed<IValidator>(validatorType);
}
}
My Autofac configurator:
public class AutofacConfigurator
{
public static void Configure()
{
var builder = new ContainerBuilder();
...
builder.RegisterType<MyFormValidator>()
.Keyed<IValidator>(typeof(IValidator<MyForm>))
.As<IValidator>()
// 2nd parameter returns IQueryable<User>
.WithParameter("users", new SqlRepository<User>(dataContext))
.InstancePerRequest();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// Register the validator factory with FluentValidation, and register
// FluentValidation as the model validator provider for the MVC framework.
// see http://www.jerriepelser.com/blog/using-fluent-validation-with-asp-net-mvc-part-3-adding-dependency-injection
var fluentValidationModelValidatorProvider =
new FluentValidationModelValidatorProvider(
new DependencyResolverValidatorFactory(container));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
fluentValidationModelValidatorProvider.AddImplicitRequiredValidator = false;
ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);
}
}
Getting the following exception:
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
I have other validators, most of which will not need data injected into them.
This is largely new ground for me (in both Autofac and FluentValidation) and am still trying to understand what I am doing here. I suspect I'm simply registering my type incorrectly. How do I fix this and properly register my type?
(My apologies if this is too similar to other questions that were already asked.)
I have zero experience with FluentValidation, but I doubt it's the cause of your issues anyway, so I'll plow forward regardless.
The exception you're getting means that Autofac can't resolve your service as 'instance per request'. There's a lot of documentation as to what this means on the Autofac documentation page. To summarize, it means that Autofac will attempt to resolve the service from a lifetime scope that is automatically created for each request sent to the webserver. When you register something as .InstancePerRequestScope() but then attempt to resolve that service outside of that scope, you'll get the DependencyResolutionException you see.
So we've established that your MyFormValidator isn't being resolved from a 'Request' scope. Why?
The custom DependencyResolverValidatorFactory you've written takes the actual IContainer that was built by Autofac, and resolves from that. This is a special type of ILifetimeScope, the 'root scope'. There's no request lifetime scope directly associated with this, so you get your exception. You need to to resolve from an ILifetimeScope that is began from the 'request' scope, or a sub-scope that is contained within the request scope.
The Autofac/MVC integration already automatically hosts a request scope (within the AutofacDependencyResolver, see the source), but your custom DependencyResolverValidatorFactory doesn't resolve from it. If you want to do that, I suppose you could modify your DependencyResolverValidatorFactory to accept the AutofacDependencyResolver instance instead, and use that to resolve.
It would look something like this:
public class DependencyResolverValidatorFactory : ValidatorFactoryBase
{
private readonly AutofacDependencyResolver resolver;
public DependencyResolverValidatorFactory(AutofacDependencyResolver resolver)
{
this.resolver = resolver;
}
public override IValidator CreateInstance(Type validatorType)
{
return resolver.RequestLiftimeScope.ResolveOptionalKeyed<IValidator>(validatorType);
}
}
Note the RequestLifetimeScope stuck in there.
Then you create this in your .Configure() method using
var resolver = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(resolver);
var fluentValidationModelValidatorProvider =
new FluentValidationModelValidatorProvider(
new DependencyResolverValidatorFactory(resolver));
That should get rid of the exception, assuming that this factory does indeed have a request to work from when creating instances of IValidators. If not, You might need to register using the default behavior (.InstancePerDependency(), where it creates a new instance every time it's requested) or a singleton (.SingleInstance()), depending on how/if validators can or should be shared.
Good luck.
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?
When Autofac resolve a component that implements IDisposable this one will be linked with scope that has been configured when you registered it. When this scope will be disposed, all linked components will be disposed too. See http://autofac.readthedocs.org/en/latest/lifetime/disposal.html for more information.
In your case, if INotificationCustomHandler is registered as InstancePerDependency (default) or InstancePerLifetimeScope, INotificationCustomHandler resolved by _container, will be disposed when _container will be disposed too.
If this is what you want, you don't have to call .Dispose on these components.
If you want to manually control the lifetime of your objects, you can create your own lifetime scope.
using(ILifetimeScope scope = this._container.BeginLifetimeScope())
{
var handler = (INotificationCustomHandler)scope.ResolveOptional(handlerType);
if(handler != null)
{
Retry.Execute(() => handler.Send(entity, destination));
}
} // handler will be disposed here if needed
you should also have a look to owned instance which acts like a mini factory.
if(!container.ComponentRegistry.IsRegistered(new TypedService(handlerType)))
{
continue;
}
Type handlerFactoryType = typeof(Func<>).MakeGenericType(
typeof(Owned<>).MakeGenericType(handlerType));
var handlerFactory = (Func<Owned<INotificationCustomHandler>>)container
.Resolve(handlerFactoryType);
using(Owned<INotificationCustomHandler> ownedHandler = handlerFactory())
{
INotificationCustomHandler handler = ownedHandler.Value;
Retry.Execute(() => handler.Send(entity, destination), 3, 500);
} // handler will be disposed here
I have a question about implementing the Dependency Injection pattern. I have a class that requires access to a web service. According to this pattern I shouldn't have my class instantiating the service as this causes a strong dependency with it. This lead me to creating a factory class that constructs my class and in its constructor passing the correct service it requires, i.e. dependencies.
What is troubling to me is that I am passing the instance of the web service client to my object but wouldn't this leave the service open?
Should I pass the entire client in as opposed to only the interface? This way I can implement IDisposable and close the connection to the service?
Thanks in advance.
Please feel free to correct any terminology, don't mean to cause confusion.
For example:
public class ProductService
{
private IProductService client;
public ProductService(IProductService client)
{
this.client = client;
}
public void DoIt()
{
client.MyWebMethod();
}
}
public class Factory
{
public static T Create<T>() where T : class
{
T item = null;
if (typeof(T) == typeof(ProductService))
{
item = new CustomerService(**new ProducttServiceClient()**) as T;
}
return item;
}
}
Yes, if you create instance yourself by new ProducttServiceClient(), then you/factory need to dispose it. That's the place where DI containers like Unity, Castle Windsor can help you and release/dispose it.
Assuming we are talking about generated service client ProducttServiceClient - subclass of ClientBase, please be aware, that if you dispose the client it will try to close opened and not aborted channels - which can lead to an exception.See this link for details
If you just pass in opened channel (System.ServiceModel.ClientBase.CreateChannel()), then you can close/abort it and reuse the client again.
Yes, if your factory class creates the service client instance, it should also be responsible for closing it. But what are you trying to achieve (except trying out dependency injection and the factory pattern)? I don't think the factory pattern gives you much in this case.
If you don't want your client to create and close the proxy every time you want to call a service operation I would recommend creating a extension method on ICommunicationObject that is responsible to do the work and then close the proxy. Then you only have to implement the logic for disposing your client once (and in one place!).
extension might look like this:
public static TResult Using<T, TResult>(this T client, Func<T, TResult> work) where T : ICommunicationObject
{
TResult res = default(TResult);
try
{
res = work(client);
client.Close();
}
catch (CommunicationException)
{
client.Abort();
throw;
} // ... more catch cases might go here...
finally
{
if (client.State != CommunicationState.Closed)
client.Abort();
}
return res;
}
your client would invoke the method like this:
using TheNameOfYourNamespaceDefiningTheExtension
return new ServiceClient().Using(client => client.MethodName(request));