unitycontainer / interception

Unity.Interception package
Apache License 2.0
22 stars 17 forks source link

System.ArgumentOutOfRangeException with VirtualMethodInterceptor and ref parameters #2

Open ENikS opened 6 years ago

ENikS commented 6 years ago

@kostemar Wrote:

I ran into a problem with the Unity.Interception extension (using Unity v4.0.1 and Unity.Interception v4.0.1) and VirtualMethodInterception.

Since the issue is a bit difficult to explain, I attached a console application that reproduces the issue. Basically, I have some "domain objects" that look something like this:

public interface IDataImportJob
{
    void Run();
}

public abstract class DataImportBase : IDataImportJob
{
    public virtual void Run()
    {
        OnRun();
    }

    protected abstract bool OnRun();
}

public interface IProductPartAndOptionMasterDataImport : IDataImportJob
{
}

public class ProductPartAndOptionMasterDataImport : DataImportBase, IProductPartAndOptionMasterDataImport
{
    private readonly IOtherObject _otherObject;

    public ProductPartAndOptionMasterDataImport(IOtherObject otherObject)
    {
        _otherObject = otherObject;
    }

    protected override bool OnRun()
    {
        var productsOk = RunProductPartAndOptionImport();

        return productsOk;
    }

    protected virtual bool RunProductPartAndOptionImport()
    {
        int partsProcessed = 42;
        ImportProductPartFromProduct(ref partsProcessed);
        return true;
    }

    [TracingCallHandler(true, true, true)]
    // if you remove the "partsProcessed" parameter here, the issue does not occur.
    protected virtual void ImportProductPartFromProduct(ref int partsProcessed)
    {
        int someParameter = 0;
        _otherObject.SomeMethod(ref someParameter);
    }
}

public interface IOtherObject
{
    void SomeMethod(ref int someArgument);
}

public class OtherObject : IOtherObject
{
    public virtual void SomeMethod(ref int someArgument)
    {
        throw new Exception("Something bad happened.");
    }
}

The TracingCallHandler is a CallHandler that can log and swallow exceptions.

Now, when I run the console application, the "Something bad happened" exception is logged as expected, but then I get a second exception (System.ArgumentOutOfRangeException) that crashes the application.

I guess the problem is that somewhere in the dynamically generated code (DynamicModule.ns.Wrapped_ ...) a ParameterCollection is created with an empty arguments array. Then, the indexer of that ParameterCollection is used with an index of 0, which will eventually result in that System.ArgumentOutOfRangeException.

If you remove the partsProcessed parameter from the ImportProductPartFromProduct method, the issue does not occur.

ENikS commented 6 years ago

I can reproduce it but have no clue how to fix. Will work on it...

witskeeper commented 6 years ago

get errors when i try to build the code image