Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot Instantiate Object Because Parameterless Constructor is Missing #4

Open
lawrence-laz opened this issue Jul 27, 2020 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@lawrence-laz
Copy link
Owner

User reported an issue of being unable to create a decorated object instance without parameterless constructor.

Reproduced here:

using Decor;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Xunit;

namespace Reproduce
{
    public class DecorRepro
    {
        public class Dependency { }
        public class Decorator : IDecorator
        {
            public async Task OnInvoke(Call call) => await call.Next();
        }
        public abstract class Base
        {
            protected Base(Dependency featureToggle)
            {
            }
            public abstract Task OnMessage();
        }
        public class Actual : Base
        {
            public Actual(Dependency featureToggle) :base(featureToggle)
            {
            }

            [Decorate(typeof(Decorator))]
            public override async Task OnMessage() => await Task.Delay(1);
        }
        [Theory, AutoMoqData]
        public void aaa(ServiceCollection serviceCollection)
        {
            var provider = serviceCollection
                .AddDecor()
                .AddTransient<Dependency>()
                .AddTransient<Decorator>()
                .AddScoped<Actual>().Decorated()
                .BuildServiceProvider();
            var sut = provider.GetService<Actual>();
        }
    }
}
@lawrence-laz lawrence-laz added the bug Something isn't working label Jul 27, 2020
@lawrence-laz lawrence-laz self-assigned this Jul 27, 2020
@lawrence-laz
Copy link
Owner Author

lawrence-laz commented Jul 27, 2020

The problem arises from the target service not having an interface with parameter-less constructor.
A workaround is to just add an interface and add it to dependency container registration.

There are 3 ways to solve this from the package perspective. In an increasing difficulty they are:

  1. Just catch these cases early and inform that it is not supported. Provide a guide for a work around using interfaces.
  2. Castle's DynamicProxy would allow to create objects using dependency container (issue here).
  3. Identify the constructor and needed parameters in Decor and resolve them manually using ServiceProvider. This steps a bit outside of this package's scope.

Looking at the future, Decor V3 will not depend on Castle.Core and will not have this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant