Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittent: Value cannot be null.Parameter name: con #229

Closed
BackToWorkMinion opened this issue Dec 4, 2015 · 4 comments
Closed

Intermittent: Value cannot be null.Parameter name: con #229

BackToWorkMinion opened this issue Dec 4, 2015 · 4 comments

Comments

@BackToWorkMinion
Copy link

Hi,

I am currently using:
id="Castle.Core" version="3.3.0" targetFramework="net45"
id="LightInject" version="3.0.2.6" targetFramework="net45"
id="LightInject.Interception" version="1.0.0.8" targetFramework="net45"

Setup:

 public class MyClass : BaseClass
 {
 }

 public abstract class BaseClass : IDisposable
 {
    public virtual void Dispose()
    {
    }
 }

T = MyClass

My code goes like this:

 public void Test()
 {            
      _serviceContainer.Register<T>();            
      _serviceContainer.Intercept(
                     sr => sr.ServiceType == typeof(T),
                     (factory, definition) => Instance.defineProxyType(definition, new MyInterceptor()));

      T instance = default(T);

        using (Instance._serviceContainer.BeginScope())
        {
            instance = (T)(Instance._serviceContainer.TryGetInstance<T>());
        }
 }

 private void defineProxyType(ProxyDeefinition definition, IInterceptor myInterceptor)
 {
      definition.Implement(
               () => myInterceptor,
               m =>m.IsDeclaredBy(definition.TargetType) && m.IsPublic)
 }

When calling the TryGetInstance, intermittently, I encounter the error. Also for GetInstance

Trying to figure out
It seems when this is called, targetField is null

 private void PushProxyInstanceIfReturnValueEqualsTargetInstance(ILGenerator il, Type returnType)
         {
             var returnValueVariable = il.DeclareLocal(returnType);
             il.Emit(OpCodes.Stloc, returnValueVariable);
             var lazyTargetType = typeof(Lazy<>).MakeGenericType(proxyDefinition.TargetType);
             var getValueMethod = lazyTargetType.GetMethod("get_Value");
             il.Emit(OpCodes.Ldarg_0);
             il.Emit(OpCodes.Ldfld, targetField);

....

Then I became confused because the method which sets value for targetField, will always return since the proxyDefinition.TargetType.IsClass is true

  private void DefineTargetField()
  {
       if (proxyDefinition.TargetType.IsClass)
        {
             return;
        }

        Type targetFieldType;
        if (proxyDefinition.UseLazyTarget)
        {
            targetFieldType = typeof(Lazy<>).MakeGenericType(proxyDefinition.TargetType);    
        }
        else
        {
            targetFieldType = proxyDefinition.TargetType;
        }

        targetField = typeBuilder.DefineField("target", targetFieldType, FieldAttributes.Private);            
    }

Please correct me if I'm wrong at this.

might be related to:
#201

StackTrace:
at System.Reflection.Emit.ModuleBuilder.GetFieldTokenNoLock(FieldInfo field)
at System.Reflection.Emit.ModuleBuilder.GetFieldToken(FieldInfo field)
at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, FieldInfo field)
at LightInject.Interception.ProxyBuilder.PushProxyInstanceIfReturnValueEqualsTargetInstance(ILGenerator il, Type returnType) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 1512
at LightInject.Interception.ProxyBuilder.PushReturnValue(ILGenerator il, Type returnType) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 1496
at LightInject.Interception.ProxyBuilder.ImplementInterceptedMethod(MethodInfo targetMethod, Int32[] interceptorIndicies) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 1712
at LightInject.Interception.ProxyBuilder.ImplementMethod(MethodInfo targetMethod) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 1680
at LightInject.Interception.ProxyBuilder.ImplementMethods() in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 1670
at LightInject.Interception.ProxyBuilder.GetProxyType(ProxyDefinition definition) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 1233
at LightInject.InterceptionContainerExtensions.CreateProxyType(Type serviceType, Type[] additionalInterfaces, IServiceFactory serviceFactory, Action2 defineProxyType, ServiceRegistration registration) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 136 at LightInject.InterceptionContainerExtensions.CreateProxyServiceRegistration(ServiceRegistration registration, Type[] additionalInterfaces, IServiceFactory serviceFactory, Action2 defineProxyType) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 171
at LightInject.InterceptionContainerExtensions.<>c__DisplayClass3.b__2(IServiceFactory serviceFactory, ServiceRegistration registration) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject.Interception\LightInject.Interception.cs:line 66
at LightInject.ServiceContainer.EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistration, IEmitter emitter) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject\LightInject.cs:line 3114
at LightInject.ServiceContainer.<>c__DisplayClass9e.b__9a(IEmitter methodSkeleton) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject\LightInject.cs:line 3739
at LightInject.ServiceContainer.<>c__DisplayClass39.b__38(IEmitter ms) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject\LightInject.cs:line 3059
at LightInject.ServiceContainer.CreateDynamicMethodDelegate(Action`1 serviceEmitter) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject\LightInject.cs:line 2980
at LightInject.ServiceContainer.CreateDelegate(Type serviceType, String serviceName, Boolean throwError) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject\LightInject.cs:line 3824
at LightInject.ServiceContainer.CreateDefaultDelegate(Type serviceType, Boolean throwError) in c:\GitHub\LightInject\NuGet\Build\Net45\LightInject\LightInject.cs:line

seesharper pushed a commit that referenced this issue Dec 9, 2015
@seesharper
Copy link
Owner

Should be covered by #229 now being fixed

@ilyabreev
Copy link

Issue is still present. Reproduced it with latest version of LightInject.Interception.cs from this repo.
"Value cannot be null. Parameter name: con".
In fact, targetField is null when passed to il.Emit(OpCodes.Ldfld, targetField); in the PushProxyInstanceIfReturnValueEqualsTargetInstance

No matter what interceptor's Invoke body is.

@ilyabreev
Copy link

    public static class CompositionRoot
    {
        public static ServiceContainer CreateContainer()
        {
            var container = new ServiceContainer();
            container.Register(typeof(CouchbaseClient), new PerContainerLifetime());
            container.Intercept(r => r.ServiceType == typeof(CouchbaseClient), sf => new CouchbaseClientProfiler());
            return container;
        }
    }

    public class CouchbaseClientProfiler : IInterceptor
    {
        public object Invoke(IInvocationInfo invocationInfo)
        {
            return invocationInfo.Proceed();
        }
    }

CouchbaseClient is class from Couchbase .NET SDK.

@seesharper
Copy link
Owner

This issue was moved to seesharper/LightInject.Interception#1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants