LightInject - для этого объекта в ядре.net не определен конструктор без параметров

У меня проблемы с получением экземпляра с использованием lightinject и.net core. Первоначально это был полный набор классов и т. Д., Но я упростил его.

В моем классе запуска ConfigureServices у меня есть следующий код;

 var container = new ServiceContainer();
 container.Register<IHasEnum, HasEnum>();
 var test = container.GetInstance<IHasEnum>();

Третья строка генерирует исключение;

System.MissingMethodException
No parameterless constructor defined for this object.

at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, bool publicOnly, bool noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 
at System.RuntimeType.CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, StackCrawlMark& stackMark) 
at System.Activator.CreateInstance(Type type, bool nonPublic) 
at System.Activator.CreateInstance(Type type) 
at LightInject.<>c.<.ctor>b__20_0(Type type) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 1695 
at LightInject.CompositionRootExecutor.Execute(Type compositionRootType) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 6165 
at LightInject.AssemblyScanner.ExecuteCompositionRoots(IEnumerable<Type> compositionRoots) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 6261 
at LightInject.ServiceContainer.GetEmitMethod(Type serviceType, string serviceName) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3077 
at LightInject.ServiceContainer.GetEmitMethodForDependency(Dependency dependency) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3453 
at LightInject.ServiceContainer.EmitPropertyDependency(IEmitter emitter, PropertyDependency propertyDependency, LocalBuilder instanceVariable) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3432
at LightInject.ServiceContainer.EmitPropertyDependencies(ConstructionInfo constructionInfo, IEmitter emitter) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3515 
at LightInject.ServiceContainer.EmitNewInstanceUsingImplementingType(IEmitter emitter, ConstructionInfo constructionInfo, Action<IEmitter> decoratorTargetEmitMethod) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3346
at LightInject.ServiceContainer.EmitNewInstance(ServiceRegistration serviceRegistration, IEmitter emitter) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3301 
at LightInject.<>c__DisplayClass147_0.<CreateEmitMethodWrapper>b__0(IEmitter ms) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3122 
at LightInject.ServiceContainer.CreateDynamicMethodDelegate(Action<IEmitter> serviceEmitter) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3044 
at LightInject.ServiceContainer.CreateDelegate(Type serviceType, string serviceName, bool throwError) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3909 
at LightInject.ServiceContainer.CreateDefaultDelegate(Type serviceType, bool throwError) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 3872 
at LightInject.ServiceContainer.GetInstance(Type serviceType) in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 2541 
at LightInject.ServiceContainer.GetInstance<TService>() in C:\projects\lightinject\build\tmp\netstandard13\Binary\LightInject\LightInject.cs:line 2591 

Рассматриваемый класс, HasEnum здесь;

public class HasEnum : IHasEnum
{
    private Colours _colours;

    public Colours PickedColour
    {
        get
        {
            return _colours;

        }
        internal set { _colours = Colours.Red; }
    }
}

В соответствии с рекомендацией исключения, я добавил конструктор по умолчанию в HasEnum, и это тот же результат. Что меня раздражает, так это то, что когда я пытаюсь сделать это в отдельном (сильно упрощенном) проекте, кажется, все работает нормально. Я проверил версию lightinject в обоих проектах, и они совпадают. Я что-то установил где-то неосознанно?

Большое спасибо

РЕДАКТИРОВАТЬ - Любопытно, что если я удаляю сеттер из свойства PickedColour, эта ошибка не возникает.

public Colours PickedColour
{
    get { return _colours; }
}

Так что, похоже, что-то связано с установщиком этого свойства enum. Даже если я поставлю пустой набор {}, это исключение выдает.

редактировать 2: интерфейс IHasEnum;

public interface IHasEnum
{
    Colours PickedColour { get; }
}

редактировать 3: Спасибо за ваши ответы. С точки зрения использования lightinject в ядре.net, нет большого количества документации. Специальная версия ядра.net говорит о том, что вы можете использовать ее следующим образом: http://www.lightinject.net/microsoft.dependencyinjection/

Я следовал этому, ошибка с моим тестовым классом сохраняется. Если я упросту тестовый класс, удалив тип enum, он будет работать нормально.

Чтобы уточнить, как именно я регистрирую сервисы, вот соответствующие фрагменты для нескольких файлов и классов;

// The startup method creates the config
public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables();
    builder.AddInMemoryCollection();
    Configuration = builder.Build();
}

// The configure method passes The configuration to a new 
// application object - this is what creates the lightinject container
public IServiceProvider ConfigureServices(IServiceCollection services)
{       
    services.AddSingleton(Configuration);
    var app = new PocApplication(Configuration); // the main section of PocApplication is below this method

    var service = services.AddPocCore(app); // This extension method is listed below, is in another file. 


    return service;
}

// This method creates the ServiceContainer
public PocApplication(IConfiguration config)
{
    var container = new ServiceContainer();

    Container = container;
    // Other items are omitted, the ServiceContainer 
    // is passed back.      
}


public static IServiceProvider AddPocCore(this IServiceCollection services, PocApplication pocApplication)
{
    var pocContainer = pocApplication.Container;        

    pocContainer.Register<IHasEnum, HasEnum>();
    // other services registered here

    return services.WrapAspNetContainer(pocApplication.Container); // another extension, shown below. 
}

public static IServiceProvider WrapAspNetContainer(this IServiceCollection services, IServiceContainer container)
{
    return container.CreateServiceProvider(services); 
    // This is the way to use lightinject to replace the container with the custom
    // one as per the documentation. 
}

Я удалил все, кроме соответствующих частей. Когда выполнение достигает домашнего контроллера, и я пытаюсь получить реализацию IHasEnum, возникает то же исключение. Я использовал регистрацию в соответствии с документацией, не уверен, как я могу заставить это работать.

Большое спасибо.

редактировать 4:

Я сузил источник ошибки - но не могу понять, почему она возникает. Реализация IHasEnum была красной сельдью - она ​​регистрируется правильно. Я нашел класс, который реализует ICompsitionRoot - как только я удалил это использование, был получен экземпляр HasEnum. В соответствии с документами lightInject ( http://www.lightinject.net/) любой класс, реализующий ICompositionRoot, будет выполнен при настройке DI. Класс композиции, реализующий этот интерфейс, необходим для создания объекта настроек из файла appsettings.json.

Чтобы продемонстрировать это, я снова покажу метод AddPocCore с добавленной строкой с вызовом метода расширения, который составляет состав конфигурации Root;

public static IServiceProvider AddPocCore(this IServiceCollection services, PocApplication pocApplication)
{
    var pocContainer = pocApplication.Container;        

    pocContainer.Register<IHasEnum, HasEnum>();        

    // The registerfrom extension method - shown below. 
    container.RegisterFrom(new ConfigurationCompositionRoot(application.Configuration));


    return services.WrapAspNetContainer(pocApplication.Container); // another extension, shown below. 
}


public static void RegisterFrom<TCompositionRoot>(this IServiceRegistry container, TCompositionRoot instance)
    where TCompositionRoot : ICompositionRoot
{
    // this is where the compose method is called. 
    instance.Compose(container);
}


// Either removing ICompositionRoot inheritance or the constructor means the error doesn't occur 
public sealed class ConfigurationCompositionRoot : ICompositionRoot
{
    private readonly IConfiguration _config;

    public ConfigurationCompositionRoot(IConfiguration config)
    {
        // I think this is where the default constructor exception method is
        // being generated, debugging shows the config object is instantiated here. 
        _config = config;
    }
    public void Compose(IServiceRegistry container)
    {
       // This is where the config is used to create the settings objects
       // which includes the database connection string. 
    }
}

Таким образом, по сути, как только я удаляю вызов метода расширения, то в ConfigurationCompositionRoot я удаляю ICompositionRoot из объявления класса (не давая перехватить lightinject), программа работает, как и ожидалось. Я просто не могу понять, как я могу использовать этот корень композиции, чтобы получить мои настройки в объект при запуске. Все это становится довольно длинным, извините за это - просто очень хочу, чтобы это работало с ядром dot net.

Еще раз спасибо.

0 ответов

Другие вопросы по тегам