What is the correct way to handle exceptions in Castle Windsor UsingFactoryMethod?

I use the Nhibernate continuity tool from the Windor tutorial:

Kernel.Register( Component.For<ISessionFactory>() .UsingFactoryMethod(config.BuildSessionFactory) .LifeStyle.Singleton, Component.For<ISession>() .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession()) .LifeStyle.PerWebRequest); 

Sometimes my call to config.BuildSessionFactory fails (maybe my mappings are wrong, or my connection string is incorrect or something else). In the debugger, I can see the Nhibernate exception. Now Windsor can no longer resolve my ISession , because the factory itself cannot be created.

The problem is that she doesn't seem to be complaining about it. Without a debugger, the exception is silently thrown, and the only sign that I have in my application is that all my ISession dependencies appear suddenly null . What is the right way to handle exceptions in UsingFactoryMethod ? Is there some way that I can say that Windsor can throw this exception in my application?

+2
exception-handling castle-windsor
source share
1 answer

The only reason I can see that the Castle is an exception is that the session is entered as a property, which forces Castle to consider it optional.

Here is how I fixed it ... I created an activator that throws an exception when it fails to set the property value:

 public class StrictComponentActivator : DefaultComponentActivator { public StrictComponentActivator(ComponentModel model, IKernelInternal kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction) : base(model, kernel, onCreation, onDestruction) { } protected override void SetUpProperties(object instance, CreationContext context) { instance = ProxyUtil.GetUnproxiedInstance(instance); var resolver = Kernel.Resolver; foreach(var property in Model.Properties) { var value = ObtainPropertyValue(context, property, resolver); if(value != null) { var setMethod = property.Property.GetSetMethod(); try { setMethod.Invoke(instance, new[] { value }); } catch(Exception ex) { throw new ComponentActivatorException( string.Format( "Error setting property {1}.{0} " + "in component {2}. " + "See inner exception for more information. " + "If you don't want Windsor to set this property " + "you can do it by either decorating it with " + "DoNotWireAttribute or via registration API.", property.Property.Name, instance.GetType().Name, Model.Name), ex, Model); } } } } private object ObtainPropertyValue(CreationContext context, PropertySet property, IDependencyResolver resolver) { if(property.Dependency.IsOptional == false || resolver.CanResolve(context, context.Handler, Model, property.Dependency)) { try { return resolver.Resolve(context, context.Handler, Model, property.Dependency); } catch(Exception e) { if(property.Dependency.IsOptional == false) { throw; } Kernel.Logger.Warn( string.Format("Exception when resolving optional dependency {0} on component {1}.", property.Dependency, Model.Name), e); } } return null; } } 

And then I configured most of my components with .Activator<StrictComponentActivator>()

+1
source share

Source: https://habr.com/ru/post/649985/


All Articles