castleproject / Core

Castle Core, including Castle DynamicProxy, Logging Services and DictionaryAdapter
http://www.castleproject.org/
Other
2.2k stars 468 forks source link

Could not find a parameterless constructor. #591

Closed LFDCC closed 2 years ago

LFDCC commented 3 years ago

I want to add a proxy to Controller ,And then I implemented this interface, IControllerActivator , Because my Controller does not have a parameterless constructor, the call CreateClassProxyWithTarget throws the exception. I want to know how to solve this problem


//ControllerActivator
 public class CustomControllerActivator : IControllerActivator
    {
        public object Create(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            Type serviceType = context.ActionDescriptor.ControllerTypeInfo.AsType();

            var target = context.HttpContext.RequestServices.GetRequiredService(serviceType);

            var proxyGenerator = context.HttpContext.RequestServices.GetRequiredService<ProxyGenerator>();
            var customInterceptors = context.HttpContext.RequestServices.GetRequiredService<IEnumerable<ICustomInterceptor>>();
            var interceptors = GetInterceptors(customInterceptors);

            var proxy = proxyGenerator.CreateClassProxyWithTarget(serviceType,target,interceptors.ToInterceptors());
            //throw execption "Could not find a parameterless constructor."
            return proxy;

        }
}
//Controller
 [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        ITestUser testUser;        

        public WeatherForecastController(ILogger<WeatherForecastController> logger, ITestUser testUser)
        {
            _logger = logger;
            this.testUser = testUser;
        }
}
jonorossi commented 3 years ago

ASP.NET Core has heaps of extensibility points, I don't understand why you'd use DynamicProxy.

LFDCC commented 3 years ago

ASP.NET Core has heaps of extensibility points, I don't understand why you'd use DynamicProxy.

I knew that using Filter would be a better choice I want to know how to solve this problem

LFDCC commented 3 years ago

ASP.NET Core has heaps of extensibility points, I don't understand why you'd use DynamicProxy.

I don't think any dynamic proxy is as good as the Filter that comes with ASP.NET Core, but I'm just wondering how to implement a proxy in Controller using castle. Core

jonorossi commented 3 years ago

The CreateClassProxyWithTarget overload you are using expects a default constructor as documented in the XML documentation:

/// <exception cref = "ArgumentException">Thrown when no parameterless constructor exists on type
///     <paramref name = "classToProxy" />.</exception>

You'll need to use an overload that accepts object[] constructorArguments.