我无法使用lightinject和.net核心检索实例。 最初这是一套全面的课程等,但我已经简化了。
在我的启动类中,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属性中删除了setter,则不会发生此错误。
public Colours PickedColour
{
get { return _colours; }
}
所以这似乎与这个枚举属性的setter有关。即使我把一个空白集{}这个例外抛出。
编辑2:IHasEnum界面;
public interface IHasEnum
{
Colours PickedColour { get; }
}
编辑3:感谢您的回复。在.net核心中使用lightinject方面,没有大量的文档。 .net核心特定版本告诉您使用它:http://www.lightinject.net/microsoft.dependencyinjection/
我已经跟着这个,我的测试类的错误仍然存在。 如果我通过删除枚举类型来简化测试类,它可以正常工作。
为了进一步明确我如何注册服务,以下是跨多个文件和类的相关代码段;
// 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/#composition-root),任何实现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拦截它)程序按预期工作。 我只是无法理解如何使用这个组合root来启动我的设置到一个对象。 整个事情变得相当长,对此感到抱歉 - 只是真的想要使用dot net core。
再次感谢。