Mustafa Çağlar Aras Mustafa Çağlar Aras - 23 days ago 6
C# Question

Can not apply commission concerns to component Late bound because it appears to be a target-less proxy. Currently those are not supported

I designed a simple unit test pattern and used the moq library. But an exception is thrown when executing Container.Resolve() method. The following is the registration method for Castle Windsor:

container.Register(Component.For<TBase>().UsingFactoryMethod(() =>
{
var mockObject = new Mock<TBase>();
var mockType = typeof(TBase);

if (container is Core.IoCContainer.IoCCore.CustomContainer)
{
var resolvingDelege = (container as Core.IoCContainer.IoCCore.CustomContainer).ResolvingTestDelegateList[mockType];

if (resolvingDelege != null)
{
resolvingDelege(mockType, mockObject);
}
}

return mockObject.Object;
})
.LifestyleTransient());


while executing "IoCCore.Container.Resolve< ISampleDataContext>();", an exception is being thrown. The exception message is "Can not apply commission concerns to component Late bound Data.Context.ISampleDataContext because it appears to be a target-less proxy. Currently those are not supported."

I searched for the problem and found that mockObject.Object is Castle.DynamicProxy.IProxyTargetAccessor. Thus, while resolving instance then code below in the Castle.MicroKernel.ComponentActivator.AbstractComponentActivator class is where the problem occurs:

protected virtual void ApplyCommissionConcerns(object instance)
{
if (Model.Lifecycle.HasCommissionConcerns == false)
{
return;
}

instance = ProxyUtil.GetUnproxiedInstance(instance);
if (instance == null)
{
// see http://issues.castleproject.org/issue/IOC-332 for details
throw new NotSupportedException(string.Format("Can not apply commission concerns to component {0} because it appears to be a target-less proxy. Currently those are not supported.", Model.Name));
}
ApplyConcerns(Model.Lifecycle.CommissionConcerns, instance);
}


The object being resolved by UsingFactoryMethod is "Castle.DynamicProxy.IProxyTargetAccessor", which is created by mock object. But, Castle Windsor assumes that IProxyTargetAccessor is created by itself instead of mock object. This causes an empty instance of CommissionConcerns is being returned from my mock instance.

Is there a possible workaround for this bug? Should I wait for an update?

Answer

I developed a workaround for this problem. I changed UseFactoryMethod method instead of the code below

Component.For<TBase>().UsingFactoryMethod(() =>
            {
                var mockObject = new Mock<TBase>();
                var mockType = typeof(TBase);

                if (container is Core.IoCContainer.IoCCore.CustomContainer)
                {
                    var resolvingDelege = (container as Core.IoCContainer.IoCCore.CustomContainer).ResolvingTestDelegateList[mockType];

                    if (resolvingDelege != null)
                    {
                        resolvingDelege(mockType, mockObject);
                    }
                }

                //The code that was changed
                //==============================================
                var type = mockObject.Object.GetType();
                var field = type.GetField("__target");

                field.SetValue(mockObject.Object, new Object());
                //==============================================

                return mockObject.Object;
            })
            .LifestyleTransient());
Comments