What is the right way to deal with exceptions in Castle Windsor's UsingFactoryMethod?

谁说我不能喝 提交于 2019-12-12 20:08:57

问题


I'm using the Nhibernate persistence facility from Windor's 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 will fail (maybe my mappings are wrong, or my connection string is invalid or whatever). In the debugger, I can see the Nhibernate exception being thrown. Now Windsor can no longer resolve my ISession either because the factory itself couldn't be instantiated.

The problem is that it doesn't seem to complain about it. Without the debugger, the exception is silently thrown away and the only symptom I have in my app is that all my ISession dependencies are suddenly null. What's the right way to deal with exceptions in UsingFactoryMethod? Is there some way I can tell Windsor to bubble up this exception to my app?


回答1:


The only why I can see Castle eating the exception is if the session is being injected as a property, which makes Castle consider it optional.

Here's how I fixed it... I created an activator that throws an exception when it fails to set a property's 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>()



来源:https://stackoverflow.com/questions/11999242/what-is-the-right-way-to-deal-with-exceptions-in-castle-windsors-usingfactoryme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!