"ContainerControlledLifetimeManager的值只能设置一次",当使用开放通用的单子注册时。

问题描述 投票:0回答:1

我用的是 Unity.Container NuGet包5.11,我想注册一个开放通用类型,使每个具体类型都是一个单子。

背景:我正在一个老式的ASP.NET WebForms应用程序中工作。我在一个老式的ASP.NET WebForms应用程序中工作 我已经做了一个粗略的重新实现 Microsoft.Extensions.Logging 像这样。

// `ILogger` is implemented elsewhere. Specifically I wrote an implementation using Serilog.
public interface ILogger
{
    void Log( LogLevel level, String messageTemplate, params Object[] args ); 
}

// Unlike `ILogger`, this `ILogger<TSourceContext>` is not implemented by the code elsewhere (that uses Serilog, described above).
// Instead, it's only implemented by the internal class below:
public interface ILogger<TSourceContext> : ILogger
{
}

internal class LoggerWithSourceContext<TSourceContext> : ILogger<TSourceContext>
{
    private readonly ILogger realLogger;

    internal LoggerWithSourceContext( ILoggerFactory factory )
    {
        if( factory == null ) throw new ArgumentNullException(nameof(factory));
        this.realLogger = factory.CreateLogger( sourceContext: typeof(TSourceContext).FullName );
    }

    public void Log( LogLevel level, String messageTemplate, params Object[] args )
    {
        this.realLogger.Log( level, messageTemplate, args );
    }
}

// This is implemented elsewhere in my Serilog code.
public interface ILoggerFactory
{
    ILogger CreateLogger( String sourceContext );
}

这是在我的Unity根容器中注册的,就像这样。

IUnityContainer rootContainer = ...
rootContainer
    .RegisterSingleton<ILoggerFactory,MySerilogLoggerFactory>()
    .RegisterSingleton( from: typeof(ILogger<>), to: typeof(LoggerWithSourceContext<>);

当使用这个时,第一次使用 ILogger<T> 解决了,它就能正常工作--但是 第二 时候 ILogger<T> 的解析失败,出现此错误。

InvalidOperationException ContainerControlledLifetimeManager只能设置一次

我可以通过使用以下方法来解决这个问题:将 Singleton 注册改为 Transient 注册。RegisterType但我希望它使用Singleton注册来减少内存或资源泄漏的风险。

IUnityContainer rootContainer = ...
rootContainer
    .RegisterSingleton<ILoggerFactory,MySerilogLoggerFactory>()
    .RegisterType( from: typeof(ILogger<>), to: typeof(LoggerWithSourceContext<>);

全栈跟踪

ContainerControlledLifetimeManager can only be set once
-2146233079
System.InvalidOperationException
   at Unity.Lifetime.ContainerControlledLifetimeManager.<>c.<SetValue>b__7_0(Object o, ILifetimeContainer c) in C:\projects\unity\Abstractions\src\Lifetime\Managers\ContainerControlledLifetimeManager.cs:line 70
   at Unity.Lifetime.ContainerControlledLifetimeManager.SetValue(Object newValue, ILifetimeContainer container) in C:\projects\unity\Abstractions\src\Lifetime\Managers\ContainerControlledLifetimeManager.cs:line 70
   at Unity.Strategies.LifetimeStrategy.PostBuildUp(BuilderContext& context) in C:\projects\unity\Container\src\Strategies\LifetimeStrategy.cs:line 86
   at Unity.UnityContainer.<>c.<.ctor>b__41_3(BuilderStrategy[] chain, BuilderContext& context) in C:\projects\unity\Container\src\UnityContainer.Resolution.cs:line 431
   at Unity.Builder.BuilderContext.Resolve(Type type, String name, InternalRegistration registration) in C:\projects\unity\Container\src\Builder\Context\BuilderContext.cs:line 177
   at Unity.Builder.BuilderContext.Resolve(Type type, String name) in C:\projects\unity\Container\src\Builder\Context\BuilderContext.cs:line 67
   at Unity.Builder.BuilderContext.Resolve(ParameterInfo parameter, Object value) in C:\projects\unity\Container\src\Builder\Context\BuilderContext.cs:line 217
   at Unity.Processors.ConstructorProcessor.<>c__DisplayClass16_0.<GetResolverDelegate>b__0(BuilderContext& c) in C:\projects\unity\Container\src\Processors\Constructor\ConstructorResolution.cs:line 77
   at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c) in C:\projects\unity\Container\src\Processors\Abstracts\MemberProcessor.cs:line 162
   at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c) in C:\projects\unity\Container\src\Processors\Abstracts\MemberProcessor.cs:line 162
   at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c) in C:\projects\unity\Container\src\Processors\Abstracts\MemberProcessor.cs:line 162
   at Unity.Strategies.BuildPlanStrategy.PreBuildUp(BuilderContext& context) in C:\projects\unity\Container\src\Strategies\BuildPlanStrategy.cs:line 88
   at Unity.UnityContainer.<>c.<.ctor>b__41_2(BuilderContext& context) in C:\projects\unity\Container\src\UnityContainer.Resolution.cs:line 363
   at Unity.UnityContainer.Unity.IUnityContainer.Resolve(Type type, String name, ResolverOverride[] overrides) in C:\projects\unity\Container\src\UnityContainer.IUnityContainer.cs:line 244
unity-container
1个回答
0
投票

现在在最新的unity版本5.11.7中,这个问题得到了解决。

© www.soinside.com 2019 - 2024. All rights reserved.