LightInject - 在.net核心

时间:2017-02-16 10:02:42

标签: c# asp.net dependency-injection asp.net-core light-inject

我无法使用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。

再次感谢。

0 个答案:

没有答案