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.
Еще раз спасибо.