Giter Club home page Giter Club logo

core's Introduction

Castle Core

Castle Core provides common Castle Project abstractions including logging services. It also features Castle DynamicProxy a lightweight runtime proxy generator, and Castle DictionaryAdapter.

See the documentation.

Releases

NuGet

See the Releases.

Debugging symbols are available in symbol packages in the AppVeyor build artifacts since version 4.1.0. For example, here are the artifacts for 4.1.0.

License

Castle Core is © 2004-2022 Castle Project. It is free software, and may be redistributed under the terms of the Apache 2.0 license.

Contributing

Browse the contributing section of our Home repository to get involved.

Building

Platforms NuGet Feed
Windows & Linux Preview Feed

On Windows

build.cmd

Compilation requires a C# 9 compiler, an up-to-date .NET Core SDK, and MSBuild 15+ (which should be included in the former).

Running the unit tests additionally requires the .NET Framework 4.6.2+ as well as the .NET Core 2.1, 3.1 and 6.0 runtimes to be installed. (If you do not have all of those installed, you can run the tests for a specific target framework using dotnet test -f <framework>.)

These requirements should be covered by Visual Studio 2022 and the .NET 6 SDK.

On Linux

./build.sh

Compilation requires an up-to-date .NET Core SDK.

Running the unit tests additionally requires the .NET Core 3.1 and 6.0 runtimes to be installed, as well as either Docker or Mono. For the latter, we recommend Mono 5.10+, though older versions (4.6.1+) might still work as well.

ℹ️ Mono runtime support: Castle Core runs with minor limitations and defects on Mono 4.0.2+ (however 4.6.1+ is highly recommended, or 5.10+ if your code uses new C# 7.x language features such as in parameters).

We test against up-to-date Mono versions in order to fix known defects as soon as possible. Because of this, if you are using an older Mono version than our Continuous Integration (CI) build, you might see some unit tests fail.

For known Mono defects, check our issue tracker, as well as unit tests marked with [Platform(Exclude = "Mono", ...)] in the source code.

Conditional Compilation Symbols

The following conditional compilation symbols (vertical) are currently defined for each of the build configurations (horizontal):

Symbol .NET 4.6.2 .NET Standard 2.x and .NET 6
FEATURE_APPDOMAIN 🚫
FEATURE_ASSEMBLYBUILDER_SAVE 🚫
FEATURE_SERIALIZATION 🚫
FEATURE_SYSTEM_CONFIGURATION 🚫
  • FEATURE_APPDOMAIN - enables support for features that make use of an AppDomain in the host.
  • FEATURE_ASSEMBLYBUILDER_SAVE - enabled support for saving the dynamically generated proxy assembly.
  • FEATURE_SERIALIZATION - enables support for serialization of dynamic proxies and other types.
  • FEATURE_SYSTEM_CONFIGURATION - enables features that use System.Configuration and the ConfigurationManager.

core's People

Contributors

aduckardt avatar alwin avatar ayende avatar blairconrad avatar cneuwirt avatar cprieto avatar drusellers avatar dtchepak avatar fabiob avatar firegrass avatar flcdrg avatar fschmied avatar hammett avatar hconceicao avatar jeremymeng avatar jevonius avatar jonorossi avatar joshrobb avatar kenegozi avatar kkozmic avatar leemhenson avatar mausch avatar mzywitza avatar rbellamy avatar roelofb avatar sellig avatar spicycode avatar stakx avatar tunatoksoz avatar vbedegi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

core's Issues

Update log4net integration to latest

I think it's time to upgrade to latest log4net version (with the new key).

This is a breaking change, as because of the new key, the log4net libraries can't use assembly redirect.

But, since our assembly retains the same key, people can assembly redirect between our new and old versions (as long as we don't change our API, which we most likely won't)

Mono: Fix remaining ignored unit tests

See parent issue: #79

These are the remaining 136 117 (1391 - 1274) unit tests that I've ignored. Feel free to send in a PR for any of them on the mono-support master branch.

I've permanently ignored a few unit tests using the [Platform(Exclude = "mono", Reason = "...")] syntax, and am using #if __MonoCS__ [Ignore("...")] #endif for those still to fix.

DynamicProxy

  • Assertion at sgen-alloc.c:460, condition '*p == NULL' not met
  • System.Type[] doesn't implement interface Castle.DynamicProxy.IInvocation
    • Fixed in 4.0.2, caused by the same defect as the Assertion at sgen-alloc.c:460, condition '*p == NULL' not met runtime crash
  • Assertion at reflection.c:2745, condition 'field' not met
  • System.InvalidCastException : Cannot cast from source type to destination type.
    • src/Castle.Core.Tests/GenericClassProxyTestCase.cs
  • System.ArgumentException : Constant does not match the defined type.
    • src/Castle.Core.Tests/DynamicProxy.Tests/ClassProxyWithDefaultValuesTestCase.cs
    • src/Castle.Core.Tests/DynamicProxy.Tests/ClassProxyWithMethodsWithOptionalParametersTestCase.cs
    • src/Castle.Core.Tests/DynamicProxy.Tests/InterfaceProxyWithMethodsWithOptionalParametersTestCase.cs
  • NUnit.Framework.AssertionException was expected
    • src/Castle.Core.Tests/BaseTestCaseTestCase.cs... was caused because peverify isn't available on mono, permanently disabled the unit test
  • Expected: Castle.DynamicProxy.Generators.GeneratorException, But was: System.ArgumentNullException
    • src/Castle.Core.Tests/BasicClassProxyTestCase.cs
  • Expected: xxxx.dll But was: /home/teamcity/buildagent/work/...
    • src/Castle.Core.Tests/ModuleScopeTestCase.cs
  • Expected: True But was: False
    • src/Castle.Core.Tests/PersistentProxyBuilderTestCase.cs -> PersistentProxyBuilder_SavesSignedFile
    • src/Castle.Core.Tests/BaseTestCaseTestCase.cs -> TearDown_SavesAssembly_IfProxyGenerated
  • Expected: True But was: False
    • src/Castle.Core.Tests/ClassWithAttributesTestCase.cs -> EnsureProxyHasAttributesOnGenericArgument
  • Expected: False But was: True
    • src/Castle.Core.Tests/DynamicProxy.Tests/ClassProxyWithDefaultValuesTestCase.cs -> MethodParameterWithDefaultValue_DefaultValueNullIsSetOnProxiedMethodAsWell

DictionaryAdapter

  • System.NullReferenceException : Object reference not set to an instance of an object
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/Behaviors/ConflictBehaviorTestCase.cs
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/Behaviors/XPathBehaviorTestCase.cs
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/XmlAdapterAcceptanceTestCase.cs
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/XmlApis/SysXmlCursorTestCase.cs
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/XmlApis/XPathMutableCursorTestCase.cs
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/XmlApis/XPathReadableCursorTestCase.cs
  • System.Xml.XPath.XPathException : variable p:v not found
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/Behaviors/XPathBehaviorTestCase.cs
  • String lengths are both 7. Strings differ at index 0. Expected: 'correct' But was: 'wrong B'
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/Behaviors/XPathBehaviorTestCase.cs
  • Expected: urn:a:T But was: T
    • src/Castle.Core.Tests/Components.DictionaryAdapter.Tests/Xml/XmlApis/XmlNodeTestCase.cs
  • Expected: 0 But was: 1
    • src/Castle.Core.Tests/Core.Tests/Internal/WeakKeyDictionaryTestCase.cs

Serilog integration modifies LoggerConfiguration.MinimumLevel

The SerilogFactory.Create(string name, Castle.Core.Logging.LoggerLevel level) overload modifies the MinimumLevel of the passed in LoggerConfiguration and overwrites it with the equivalent logging level to the Castle LoggerLevel enum. Each call of the Create method will modify the single LoggerConfiguration object with the level being passed in.

There is no need for the Serilog integration to support this overload, it is only there for loggers that don't support levels (e.g. ConsoleLogger, TraceLogger) which use LevelFilteredLogger. It just confuses things to have two logging frameworks filtering by log levels. Both log4net and NLog integrations throw a NotSupportedException for this overload.

var config = new LoggerConfiguration()
    .WriteTo....

var factory = new SerilogFactory(config);
var logger = factory.Create("MyLogger", LoggerLevel.Debug); <-- config has been modified by the factory

An unhandled exception of type 'System.NullReferenceException' occurred in DynamicProxyGenAssembly2

I want to write an Attribute with Castle DynamicProxy Interceptor (like OnMethodBoundaryAspect in PostShart) with handling Exceptions so
I wrote something like this :

:: STEP 1 ::

I wrote a simple InterceptorAttribute class :

[AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)]
public class InterceptorAttribute : System.Attribute
{

    public Type Interceptor { get; set; }

    public string Methods { get; set; }

    public InterceptorAttribute(Type interceptor)
    {

        this.Interceptor = interceptor;
    }
}

:: STEP 2 ::

I wrote MethodBoundaryAspect class

public abstract class MethodBoundaryAspect : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        try
        {
            var method = invocation.Method.Name;
            if (this.Methods != null)
            {
                if (!this.Methods.Contains(method))
                {
                    invocation.Proceed();
                    return;
                }
            }
            ExecuteBefore(invocation);
            invocation.Proceed();
            ExecuteAfter(invocation);
        }
        catch (Exception ex)
        {

            HandleException(invocation, ex);
        }
    }

    public string[] Methods { get; set; }

    public MethodBoundaryAspect(string[] methods = null)
    {
        this.Methods = methods;
    }

    protected abstract void ExecuteAfter(IInvocation invocation);
    protected abstract void ExecuteBefore(IInvocation invocation);
    protected abstract void HandleException(IInvocation invocation, Exception ex);
}

:: STEP 3 ::

I wrote a Helper class for registration

public static class Interceptor
{
    public static TClass Register<TClass>()
        where TClass : class,new()
    {
        var interceptors = typeof(Calculator).GetCustomAttributes(typeof(InterceptorAttribute), false);

        var customInterceptor = ((InterceptorAttribute)interceptors[0]);
        string[] methods = customInterceptor.Methods == null ? null : customInterceptor.Methods.Split(',');
        ConstructorInfo ctorCustom = customInterceptor.Interceptor.GetConstructor(new[] { typeof(string[]) });
        var instanceCustom = (IInterceptor)ctorCustom.Invoke(new object[] { methods });

        ProxyGenerator generator = new ProxyGenerator();
        var tc = generator.CreateClassProxy<TClass>(instanceCustom);
        return tc;
    }

    public static TClass Register<TClass>(ProxyGenerationOptions options, params IInterceptor[] interceptors)
        where TClass : class,new()
    {
        ProxyGenerator generator = new ProxyGenerator();
        var tc = generator.CreateClassProxy<TClass>(options, interceptors);
        return tc;
    }
}

:: STEP 4 ::

I wrote simple Interceptor for my class

public class CalculatorInterceptor : MethodBoundaryAspect
{
    public CalculatorInterceptor( string[] methods )
        : base( methods ) {

    }
    protected override void ExecuteBefore( Castle.DynamicProxy.IInvocation invocation ) {
        Console.WriteLine( "Start" );
    }

    protected override void ExecuteAfter( Castle.DynamicProxy.IInvocation invocation ) {
        Console.WriteLine( "End" );
    }

    protected override void HandleException(Castle.DynamicProxy.IInvocation invocation, Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

:: STEP 5 ::

I wrote a simple Claculator class and bound Interceptor to "Div" method of it not for all

[Interceptor( typeof( CalculatorInterceptor ) , Methods="Div" )]
public class Calculator {
    public virtual int Add( int a , int b ) {
        var c = a + b;
        Console.WriteLine( c );
        return c;
    }

    public virtual int Sub( int a , int b ) {
        var c = a - b;
        Console.WriteLine( c );
        return c;
    }

    public virtual int Mult( int a , int b ) {
        var c = a * b;
        Console.WriteLine( c );
        return c;
    }

    public virtual int Div( int a , int b ) {
        var c = a / b;
        Console.WriteLine( c );
        return c;
    }

}

:: STEP 6 ::

as final step , I want to use these classes now

class Program
{
    static void Main(string[] args)
    {
        var calc = Interceptor.Register<Calculator>();

        //Error Here****************************************************************
        calc.Div(11, 0);
        //Error Here****************************************************************

        Console.ReadKey();
    }
}

so when I run it :

first I can catch correct exception , It is my goal :D (with HandleException() method)

Attempted to divide by zero.

but immediately after it DynamicProxy show this error :( (I want to skip any throwing exception only catch it with my HandleException() method like Postsharp that I can Continue after Exceptions)

THIS ERROR FAIL MY GOALS :(

An unhandled exception of type 'System.NullReferenceException' occurred in DynamicProxyGenAssembly2

Additional information: Object reference not set to an instance of an object.

   at Castle.Proxies.CalculatorProxy.Div(Int32 a, Int32 b)
   at ConsoleApplication1.Program.Main(String[] args) in c:\...\ConsoleApplication1\ConsoleApplication1\Program.cs:line 29
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Seams this error from Castle.DynamicProxy
Can anyone check it ?

I uploaded a sample in my OneDrive with above details and error
Download My Sample

Problem with explicit interface properties of mixins

Hello,

there seems to be a problem with explicit interface properties of mixin objects.
Example :
If I use a ChildImpl object as mixin in the CreateClassProxy method, I end up with a proxy class with 2 Parent properties for different types. This should be impossible...

/// <summary>
/// Denotes a node within a parent/child hierarchy.
/// </summary>
public interface IChild
{
    /// <summary>
    /// Gets or Sets the Parent
    /// </summary>
    object Parent
    {
        get;
        set;
    }
}

/// <summary>
/// Denotes a node within a parent/child hierarchy.
/// </summary>
/// <typeparam name="TParent">The type of parent.</typeparam>
public interface IChild<TParent> : IChild
{
    /// <summary>
    /// Gets or Sets the Parent
    /// </summary>
    new TParent Parent
    {
        get;
        set;
    }
}


public class ChildImpl : IChild<string>
{
    public string Parent
    {
        get;
        set;
    }

    object IChild.Parent
    {
        get
        {
            return this.Parent;
        }
        set
        {
            this.Parent = value as string;
        }
    }
}

Support method level interception

I've been searching around to see if it is possible to use interceptors for method level interception, and came across the following from the docs:

"The InterceptorAttribute is defined in a way that allows you to put it not only on classes, but on any other target where custom attribute is allowed, like interface or a method. However Windsor will ignore the attribute unless it's on component's implementation class. This permissive behavior was introduced to allow people to add support for other targets by building custom extensions."

I think adding a fine grained control for interception at the method level would be a great thing for general purpose aspects such as logging, performance counters, etc.

ProxyGenerationOptions.AdditionalAttributes not part of cache key

The following test is red because the second CreateClassProxyType() returns the same type although the AdditionalAttributes differ.

The reason is that ProxyGenerationOptions.Equals() doesn't include AdditionalAttributes, which is important for the cache look-up in ClassProxyGenerator.

Isn't AdditionalAttributes also missing in the (de)serialization methods of ProxyGenerationOptions?

[TestFixture]
public class CustomAttributes
{
  [AttributeUsage (AttributeTargets.Class)]
  public class MyAttribute1 : Attribute { }

  [AttributeUsage (AttributeTargets.Class)]
  public class MyAttribute2 : Attribute { }

  public abstract class Foo  { }

  [Test]
  public void Test ()
  {
    var proxyBuilder = new DefaultProxyBuilder();

    var attribute1Ctor = typeof(MyAttribute1).GetConstructors().Single();
    var attribute2Ctor = typeof(MyAttribute2).GetConstructors().Single();

    var type1 = proxyBuilder.CreateClassProxyType(
        typeof (Foo),
        new Type[0],
        new ProxyGenerationOptions
        {
            AdditionalAttributes = { new CustomAttributeBuilder(attribute1Ctor, new object[0]) }
        });

    var type2 = proxyBuilder.CreateClassProxyType(
        typeof (Foo),
        new Type[0],
        new ProxyGenerationOptions {
            AdditionalAttributes = { new CustomAttributeBuilder(attribute2Ctor, new object[0]) }
        });

    Assert.AreNotSame(type1, type2);
  }
}

ProxyGenerator cache does not take into account AdditionalAttributes

When generating Proxy types, the CacheKey does not take into account the AdditionalAttributes specified on the ProxyGenerationOptions which causes a cache hit to return a Proxy that does NOT have the AdditionalAttributes applied to it if a previous Proxy class has already been generated for the same type.

The solution to fix this is for the Equality/GetHashCode operation on ProxyGenerationOptions to take into consideration the AdditionalAttributes and cause a cache miss, forcing the generation of a new type that will have the correct attributes applied to it.

Can not use latest Castle.Core-NLog

Hi,

I use Castle Windsor and NLog. I updated nuget package Castle.Core-NLog to v3.3.0 (latest). Then I got an error.

Exception:
Could not convert string 'Castle.Services.Logging.NLogIntegration.NLogFactory,Castle.Services.Logging.NLogIntegration,Version=3.2.0.0, Culture=neutral,PublicKeyToken=407dd0808d44fbdc' to a type.

Can you please update the "Castle.Facilities.Logging" components to sup­port the latest Castle.Core-NLog version.

Semantic logging support for ILogger

It would be nice to provide methods on ILogger (or sub-interface) that support the concepts of semantic logging - for example to be able to have a logging implementation that uses some of the ETW (Event Tracing for Windows) classes in .NET 4.5.

Castle doesn't need to implement ETW itself (though that may be also beneficial), but just extend the ILogger interface so that objects can be passed through to a custom implementation, rather than just strings.

Castle.Core-log4net update problem

Hi,

I use Castle Windsor and Log4Net. I updated nuget package Castle.Core-log4net to v3.3.0 (latest). Then I got an error.

Exception:
Could not convert string 'Castle.Services.Logging.Log4netIntegration.Log4netFactory,Castle.Services.Logging.Log4netIntegration,Version=3.2.0.0, Culture=neutral,PublicKeyToken=407dd0808d44fbdc' to a type.

Inner Exception:
Could not load file or assembly 'Castle.Services.Logging.Log4netIntegration, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)":"Castle.Services.Logging.Log4netIntegration, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc

I think Castle.Windsor-log4net package does not work with this new Castle.Core-log4net version. As I see, Castle.Core-log4net package is pretty old.

Can you update it? Also, It would be nice to work with Log4Net's latest version.

Thank you.

build NuGet and Zip packages from TeamCity

Spun off from #48.

We should have a tool to reduce (or eliminate) the amount of manual work required to create the NuGet packages (both binary and symbol). Eventually we'll probably want to hook this up to the TeamCity build, but initial investigation will explore something as simple as a batch file that can be run after a build, just to demonstrate the concept.

AttributeUtil support for reflection only context

AttributeUtil methods like .HasAttribute is useful for trying to determine if you want to REALLY load an assembly into the execution context when it's in the reflection only context, but you can't call GetCustomAttributes on a member of an reflection only assembly.
The workaround, at least for HasAttribute (which only determines if the member has the attribute but doesn't need to actually materialize it) is to use CustomAttributeData.GetCustomAttributes().
Obviously this won't work for any usage that requires the instance of the attribute itself.

SerilogLogger implementation bug

Hi,

I just discovered a rather annoying issue in the SerilogLogger implementation.
Calling

Fatal(string messageTemplate, Exception exception) 

delegates to

Logger.Fatal(string messageTemplate, params object[] propertyValues)

which essentially makes the exception dissapear.

I've just hunted down this bug, and can confirm that FatalFormat(Exception exception, string format) works correctly.

I would guess a simple switch in the parameters would make it work as intended, but I'm not sure.

Basically I'm guessing there might be some issues with the current ILogger interface for supporting Serilog's semantic logging?

better readme

We need readme that's more useful than the one we have now.

A few ideas

  • Put our logo
  • Tweet-long description of what this project is
  • Simple code examples
    • for DynamicProxy
    • for DictionaryAdapter
  • Important links

Dynamicproxy defaultvalue issue

Hi,

I've a simple class:

public class MyClass
{
    public virtual void MyMethod(string str = null)
    {
        Console.WriteLine(str);
    }
}

When I check

typeof(MyClass).GetMethod("MyMethod").GetParameters()[0].DefaultValue

it's null (as expected). But if I create a dynamicproxy

var gen = new ProxyGenerator(new DefaultProxyBuilder());
var proxy = gen.CreateClassProxy<MyClass>();

Then I check

proxy.GetType().GetMethod("MyMethod").GetParameters()[0].DefaultValue

It is not null, it is System.Reflection.Missing

This causes a problem when I proxy an ASP.NET MVC Controller with a method which has a default parameter as null such which is defined as:

public virtual ActionResult Login(string returnUrl = "/", string loginMessage = null)

I use proxy since I want to intercept the method call.

Is this a bug or known situation.

adjust "InternalsVisibleTo" message depending on caller?

Over at FakeItEasy/FakeItEasy#157, we're having a lively discussion of how to provide the most useful error message when we're unable to create a fake due to an exception being thrown from ProxyGenerator.CreateClassProxy.

Our current solution does not include the exception message in the output, and we feel that's hurting our users - many of the DynamicProxy exceptions include information that would really help diagnose and resolve problems.

We were looking at changing our error reports to use the exception message as the reason for failure, but noticed a discrepancy between the way FakeItEasy has been advising users to add InternalsVisibleTo attributes and the way the Castle exception does.

Castle's message suggests adding [assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)], which is kind of cool, and saves the user having to worry about the string to supply to InternalsVisibleTo. We found two downsides to this approach, though.

The first is that the assembly containing the type to be proxied (or generic arguments to the type) may not have a reference to Castle.Core. This happens in many FakeItEasy use cases. Then, the instruction to add InternalsVisible.ToDynamicProxyGenAssembly2 won't work, and might confuse the users.

The second wrinkle is that the text of InternalsVisible.ToDynamicProxyGenAssembly2 doesn't contain the public key for the assembly, so it won't work with strong-named assemblies. This is something that FakeItEasy has been working around by detecting the strong-namedness of the assembly containing the internal/private type that's causing problems.

We were discussing ways to work around the possible differences in the Castle error message and our desired errors, and a colleague suggested that perhaps some of these pain points affect other Castle users and we should just approach the Castle team about alternative exception messages.

What do you think about detecting whether the assembly of the problem type already references Castle, and is strong-named, and having the thrown exception contain a tailored message that could be more easily used by the clients?

If there's interest in the concept, but no resources available, I'd be happy to give it a try and submit a pull request.

Endless loop when serializing a RemotableInvocation

var remotableInvocation = new RemotableInvocation(null);

var binaryFormatter = new BinaryFormatter();

// After running ~50 sec on my system Serialize() eventually throws a 
// SerializationException ("The internal array cannot expand to greater 
// than Int32.MaxValue elements"):
binaryFormatter.Serialize(new MemoryStream(), remotableInvocation);

The reason is

info.AddValue("invocation", new RemotableInvocation(this));
(maybe a copy paste error happened in commit castleproject-deprecated/Castle.DynamicProxy-READONLY@3f6fd92).

It seems that there are no automated tests for the serialization of a RemotableInvocation instance.

Automate release process

As @kkozmic mentiones in FakeItEasy/FakeItEasy#179,

the whole release process for Castle is manual, therefore requires some time aside to actually do it.
Ideally, it'd be fully automated, so there's a lot that can be done there to improve it.

What can we do about that?

@castleproject/owners, I took a desultory look around the project for some sort of "how to release", but couldn't find anything. Did I miss it?
Either way, I'm keen to help make releasing easier, if anyone's interested in helping me understand the process. Let's chat.

Mono support for Castle Core

Over the last month I've spent a little bit of time trying to get our build set up working well for Mono, so that I could look into #72 knowing any new unit tests would then be running on our CI server.

This issue follows on from a thread on the mailing list which didn't yield any results.

So far I've:

  • Fixed a bunch of small issues (e.g. b320a57, 8cf8c3c, e33c78b)
  • Removed the really old Mono 2.6 and 2.8 configurations and replaced them with a Mono 3.10 for now (7654511).
  • Changed the way we run unit tests on Mono (4234289).
  • Attempted to fix unit tests failing on Mono on Linux but not OSX with errors like "Missing method .ctor in assembly ..., type ExtensionAttribute" (86df41f, 3080c4c).

I'm now stuck with these strange missing constructor errors. It seems Mono on Linux isn't liking the NLog and Serilog assemblies. Following is the error message running unit tests on Mono 3.10 on the Ubuntu TeamCity agent:

Missing method .ctor in assembly /home/teamcity/buildagent/work/16de7b8c88ab14af/lib/net45/NLog.dll, type System.Runtime.CompilerServices.ExtensionAttribute
Can't find custom attr constructor image: /home/teamcity/buildagent/work/16de7b8c88ab14af/lib/net45/NLog.dll mtoken: 0x0a000018

(http://builds.castleproject.org/viewType.html?buildTypeId=Core_MasterMono310)

I've read mentions that this type of error is caused by the fact ExtensionAttribute moved assembly between .NET 4.0 and 4.5 via a TypeForwardedTo, but I'm trying to avoid building log4net, NLog and Serilog from source in our build.

I'd like if we can remove the MONO310 build configuration completely and compile using the NET45 one. The only reason I've kept it for now is so I could easily switch between using lib/net40 and lib/net45 binaries without affecting anything else. You'll see that I've disabled the MONO define by renaming it so all that conditional code is built on Mono.

ParameterBuilder.SetConstant fails when using a default value of null

Castle.DynamicProxy.Generators.Emitters.DefineParameters line 162 fails if one of the parameters passed in is a nullable type with a default value of null.

To reproduce change the default value in ClassWithMethodWithParameterWithDefaultValue.Method to null.

public class ClassWithMethodWithParameterWithDefaultValue
{
    public virtual void Method(int? value = null)
    {  }
}

Run test MethodParameterWithDefaultValue_DefaultValueIsSetOnProxiedMethodAsWell.

    [Test]
    public void MethodParameterWithDefaultValue_DefaultValueIsSetOnProxiedMethodAsWell()
    {
        var proxiedType = generator.CreateClassProxy<ClassWithMethodWithParameterWithDefaultValue>().GetType();

        var parameter = proxiedType.GetMethod("Method").GetParameters().Single(paramInfo => paramInfo.Name == "value");

        Assert.True(parameter.HasDefaultValue);
        Assert.AreEqual(3, parameter.DefaultValue);
    }

Castle.DynamicProxy - invalid CompositionInvocation type used when code uses interface proxies with and without InterceptorSelector

In CreateInterfaceProxyWithoutTarget, when user code creates proxies of the same type, but some without IInterceptorSelector and some with it, the proxy components generated second will end up being invalid, e.g:

using System;
using System.Reflection;
using Castle.DynamicProxy;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Testing.Common.Model.DependenciesResolution.Windsor.Tests.Bugs
{
    /// <summary>https://github.com/castleproject/Core/issues/14</summary>
    [TestClass]
    public class InterfaceProxyInvocationTypeCachingBug
    {
        [TestMethod]
        public void BugExists()
        {
            var ProxyGenerator = new ProxyGenerator();
            var someInstanceOfProxyWithoutSelector = (IService)ProxyGenerator.CreateInterfaceProxyWithoutTarget(interfaceToProxy: typeof(IService), interceptors: new IInterceptor[] { new DummyInterceptor() });
            var someInstanceOfProxyWithSelector = (IService)ProxyGenerator.CreateInterfaceProxyWithoutTarget(interfaceToProxy: typeof(IService), interceptors: new IInterceptor[] { new DummyInterceptor() }, options: new ProxyGenerationOptions { Selector = new DummyInterceptorSelector() });

            // This runs fine
            someInstanceOfProxyWithoutSelector.DoSomething();
            // This will throw System.InvalidProgramException
            someInstanceOfProxyWithSelector.DoSomething();
        }

        public interface IService
        {
            void DoSomething();
        }

        public class DummyInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
            }
        }

        public class DummyInterceptorSelector : IInterceptorSelector
        {
            public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
            {
                return interceptors;
            }
        }

    }
}

The reason this is happening is because Castle generates a dedicated IInvocation type for each method of the proxied service type. The type derives from CompositionInvocation, which has two constructors, but only one constructor for the generated type is added, which - that depends on whether a selector is being used or not. This can be seen here:
https://github.com/castleproject/Core/blob/master/src/Castle.Core/DynamicProxy/Generators/CompositionInvocationTypeGenerator.cs : line 39

However the generated IInvocation with just one constructor is then reused from cache regardless whether the constructor is right for the provided ProxyGenerationOptions.Selector:
https://github.com/castleproject/Core/blob/master/src/Castle.Core/DynamicProxy/Contributors/InterfaceProxyWithoutTargetContributor.cs
line 76:

    var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, invocationInterfaces, /* Issue cause: ProxyGenerationOptions is not part of cache key */ null);

Strangely enough, i had some cases when on invocation, the Constructor with completely mismatched arguments (even typewise!) returns successfully. The program only protested on the invocation's Proceed() method because there is some null object access attempt.

Some solutions that come to my mind:

  • always overload both constructors of CompositionInvocation and keep the caching behaviour as is
  • the Cache key should include ProxyGenerationOptions
  • the caching should be refactored so the cache key used takes all the information that differentiate the generated types

P.S. I think this happens elsewhere, e.g. in:
https://github.com/castleproject/Core/blob/master/src/Castle.Core/DynamicProxy/Contributors/InterfaceProxyTargetContributor.cs
Possibly in more places near usages of CompositionInvocationTypeGenerator constructor.
I've wasted couple days on this one, so forgive me for the report not being exhaustive in this regard. If I find some more time I might elaborate.

ProxyGenerationException proxying the same generic interface multiple times

I've made a gist to demonstrate the ProxyGenerationException I get when trying to mock an interface with multiple observers.

The issue seems to only occur when running at least 3 observers (2 is fine strangely).

Test Outcome:   Failed
Test Duration:  0:00:00.211

Result StackTrace:  
at Castle.DynamicProxy.Generators.TypeElementCollection`1.Add(TElement item)
   at Castle.DynamicProxy.Contributors.CompositeTypeContributor.CollectElementsToProxy(IProxyGenerationHook hook, MetaType model)
   at Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
   at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.<>c__DisplayClass1.<GenerateCode>b__0(String n, INamingScope s)
   at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
   at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
   at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
   at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
   at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
   at Moq.Mock`1.<InitializeInstance>b__2()
   at Moq.PexProtector.Invoke(Action action)
   at Moq.Mock`1.InitializeInstance()
   at Moq.Mock`1.OnGetObject()
   at Moq.Mock`1.get_Object()

Result Message: Castle.DynamicProxy.ProxyGenerationException : Duplicate element: Castle.DynamicProxy.Generators.MetaMethod

The issue lies in this block of code @kkozmic

Currently using Moq 4.2.1502.0911

auto-generate ending copyright year in NuGet packages

Back when I fixed castleproject/Windsor#57, I added a bit where the current year is put in as the "end" copyright year in the NuGet packages.
I hadn't done that when I fixed #49, and it's been eating me up inside ever since I think about it from time to time. Now that we have a new year, it's actually become relevant.

Any interest in me upgrading the Core "Pack" task so it does the same thing?

Add PCL assembly to the NuGet package

I'm just throwing this out there although I've no idea if it's possible.

Ideally it would target the earliest versions of everything, i.e. net40, win8, sl4 and wp7 but if some or all of those need to be bumped to later versions, or if one of win8 or wp7 needs to be dropped then so be it. The idea is how to support as wide as possible and as early as possible, keeping the effort involved reasonable.

The reason I'm raising this is that we've had a few requests to support more platforms in FakeItEasy but Castle.Core is the restricting factor. We can only support the platforms which Castle.Core supports.

Where can I get the XSD document about the XML configuration?

When I use castle and register components in XML,where can I get the XSD document?

And another question is the latest "Castle.Facilities.Logging" Component(Version=3.2.0.0) seems that it does not support the latest "Castle.Services.Logging.NLogIntegration" Component(Version=3.3.0.0) . Can you please fix that?

Mono: runtime crash with DynamicProxy: Assertion at reflection.c:2745, condition 'field' not met

As discussed on the mailing list, below is a console app that is compiling well on Mac but crashing Mono at runtime. It is compiling and running fine on .NET/Windows.

Here is the repo that has this file as part of a ready to repro solution: https://github.com/floydpink/Crash-Repro

And the output along with the stack trace and the crash dump from Xamarin Studio: http://paste.ubuntu.com/9376527/

(The larger project where I am trying to get this for AOP logging is this one)

Thanks!

using System;
using System.Linq.Expressions;
using Castle.DynamicProxy;
using StructureMap;

namespace Crash_Repro {
    public class Program {
        private static void Main(string [] args) {
            // Initialize the StructureMap IoC container with DynamicProxy based interception for logging
            Bootstrapper.Initialize();

            // Initialize the view and get something done
            IView view = new MyView();
            view.PrintNameAndAge();

            Console.ReadKey(true);
        }
    }

    #region Dummy View

    public interface IView {
        bool NeedFemaleName { get; }
        void PrintNameAndAge();
    }

    public class MyView : IView {
        private readonly ILogic _logic;

        public MyView() {
            _logic = Bootstrapper.GetLogic<IView, ILogic>(this);
        }

        public bool NeedFemaleName { get { return false; } }

        public void PrintNameAndAge() {
            Console.WriteLine("Name: {0} | Age: {1}", _logic.GetName(), _logic.GetAge());
        }
    }

    #endregion

    #region Logic - depends on Service

    public interface ILogic {
        string GetName();
        int GetAge();
    }

    public class MyLogic : ILogic {
        private readonly IService _service;
        private readonly IView _view;

        public MyLogic(IView view, IService service) {
            _view = view;
            _service = service;
        }

        public string GetName() {
            return _view.NeedFemaleName ? _service.GetFemaleName() : _service.GetMaleName();
        }

        public int GetAge() {
            return _service.GetAge();
        }
    }

    #endregion

    #region Service

    public interface IService {
        string GetMaleName();
        string GetFemaleName();
        int GetAge();
    }

    public class MyService : IService {
        public string GetMaleName() {
            return "John Doe";
        }

        public string GetFemaleName() {
            return "Jane Doe";
        }

        public int GetAge() {
            return 42;
        }
    }

    #endregion

    #region Dynamic Proxy

    public class DynamicProxy {
        public static Expression<Func<T, T>> MyInterceptorFor<T>() {
            return s => CreateInterface(typeof (T), s);
        }

        private static T CreateInterface<T>(Type interfaceType, T concreteObject) {
            return (T) new ProxyGenerator().CreateInterfaceProxyWithTargetInterface(interfaceType, concreteObject, new MyInterceptor());
        }
    }

    public class MyInterceptor : IInterceptor {
        public void Intercept(IInvocation invocation) {
            Console.WriteLine("Called {0}::{1}\n", invocation.TargetType.Name, invocation.Method.Name);
            invocation.Proceed();
        }
    }

    #endregion

    #region StructureMap Boostrapper

    public static class Bootstrapper {
        private static readonly Container _container = new Container();

        public static void Initialize() {
            _container.Configure(c => {
                                     c.For<ILogic>().DecorateAllWith(DynamicProxy.MyInterceptorFor<ILogic>()).Use<MyLogic>();
                                     c.For<IService>().DecorateAllWith(DynamicProxy.MyInterceptorFor<IService>()).Use<MyService>();
                                 });
        }

        public static TLogic GetLogic<TView, TLogic>(TView view) {
            return _container.With(view).GetInstance<TLogic>();
        }
    }

    #endregion
}

Not proxied methods on class proxy with target should forward to the target [DYNPROXY-183]

Relogging YouTrack issue logged by Krzysztof 2 years ago.
http://issues.castleproject.org/youtrack/issue/DYNPROXY-183


Currently when we have a proxyable method on a class proxy with target, and chose not to proxy it, the default body of the method on the proxy object will be invoked (same behavior as inheritance-base class proxy).

The correct behavior should be to forward the call to the target object instead, like all the other "with target" proxy types are doing.

Create proxy with generic constraint fails on Mono

The following works on Windows/.NET but fails on Mac / Mono. Not sure if this is related to #72. This case was derived from NSubstitute issue 174. Tested with Castle.Core 3.3.3.

using System;
using Castle.DynamicProxy;

namespace Sample {
    class MainClass {
        public static void Main (string[] args) {
            var proxyGenerator = new ProxyGenerator ();
            IInterceptor interceptor = new StandardInterceptor ();      
            var sub = proxyGenerator.CreateInterfaceProxyWithoutTarget<IBar>(new [] {interceptor}); 
            Console.WriteLine (sub.GetType());
        }
    }
    public interface IFoo<T>{ }
    public interface IBar{
        void DoStuff<T1, T2> () where T1 : IFoo<T2>;
    }
}

Stacktrace:

System.ArrayTypeMismatchException: Source array type cannot be assigned to destination array type.
  at at (wrapper stelemref) object:virt_stelemref_sealed_class (intptr,object)
  at Castle.DynamicProxy.Generators.Emitters.GenericUtil.AdjustGenericConstraints (System.Reflection.MethodInfo methodToCopyGenericsFrom, System.Reflection.Emit.GenericTypeParameterBuilder[] newGenericParameters, System.Type[] originalGenericArguments, System.Type[] constraints) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.Emitters.GenericUtil.CopyGenericArguments (System.Reflection.MethodInfo methodToCopyGenericsFrom, System.Collections.Generic.Dictionary`2 name2GenericType, Castle.DynamicProxy.Generators.Emitters.ApplyGenArgs genericParameterGenerator) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.Emitters.GenericUtil.CopyGenericArguments (System.Reflection.MethodInfo methodToCopyGenericsFrom, System.Reflection.Emit.TypeBuilder builder, System.Collections.Generic.Dictionary`2 name2GenericType) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CopyGenericParametersFromMethod (System.Reflection.MethodInfo methodToCopyGenericsFrom) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.InvocationTypeGenerator.Generate (Castle.DynamicProxy.Generators.Emitters.ClassEmitter class, Castle.DynamicProxy.ProxyGenerationOptions options, INamingScope namingScope) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Contributors.InterfaceProxyWithoutTargetContributor.GetInvocationType (Castle.DynamicProxy.Generators.MetaMethod method, Castle.DynamicProxy.Generators.Emitters.ClassEmitter emitter, Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Contributors.InterfaceProxyWithoutTargetContributor.GetMethodGenerator (Castle.DynamicProxy.Generators.MetaMethod method, Castle.DynamicProxy.Generators.Emitters.ClassEmitter class, Castle.DynamicProxy.ProxyGenerationOptions options, Castle.DynamicProxy.Contributors.OverrideMethodDelegate overrideMethod) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementMethod (Castle.DynamicProxy.Generators.MetaMethod method, Castle.DynamicProxy.Generators.Emitters.ClassEmitter class, Castle.DynamicProxy.ProxyGenerationOptions options, Castle.DynamicProxy.Contributors.OverrideMethodDelegate overrideMethod) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate (Castle.DynamicProxy.Generators.Emitters.ClassEmitter class, Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType (System.String typeName, System.Type proxyTargetType, System.Type[] interfaces, INamingScope namingScope) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator+<>c__DisplayClass1.<GenerateCode>b__0 (System.String n, INamingScope s) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType (Castle.DynamicProxy.Generators.CacheKey cacheKey, System.Func`3 factory) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode (System.Type proxyTargetType, System.Type[] interfaces, Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget (System.Type interfaceToProxy, System.Type[] additionalInterfacesToProxy, Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget (System.Type interfaceToProxy, System.Type[] additionalInterfacesToProxy, Castle.DynamicProxy.ProxyGenerationOptions options) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (System.Type interfaceToProxy, System.Type[] additionalInterfacesToProxy, Castle.DynamicProxy.ProxyGenerationOptions options, Castle.DynamicProxy.IInterceptor[] interceptors) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (System.Type interfaceToProxy, Castle.DynamicProxy.IInterceptor[] interceptors) [0x00000] in <filename unknown>:0
  at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget[IBar] (Castle.DynamicProxy.IInterceptor[] interceptors) [0x00000] in <filename unknown>:0
  at Sample.MainClass.Main (System.String[] args) [0x00018] in Program.cs:12

DynamicProxy Throw NullReferenceException When Intercepted Method Throw Eaten Exception

The issue will happen all of the below condition met:

  1. The intercepted method has return value.
  2. The intercepted method throws an exception.
  3. The above exception is handled in _public void Intercept(IInvocation invocation)_ and it is NOT re-thrown.

We put our logging logic when the exception happens and since we do not intend to crash the application. Therefore such exception does not re-thrown.

Currently I can workaround this by putting below code in _finally block_:

if (!invocation.Method.ReturnType.IsClass
    && !invocation.Method.ReturnType.IsInterface
    && invocation.Method.ReturnType.Name != "Void"
    && invocation.Method.ReturnParameter != null
    && invocation.ReturnValue == null)
        invocation.ReturnValue = Activator.CreateInstance(invocation.Method.ReturnType);

However, it might be better to handle this in the framework itself.

Interceptor Selectors under CreateClassProxy are provided a System.RuntimeType rather than a System.Type

When writing an implementation of an IInterceptorSelector that is dependent on the proxied type I have found that the type argument given to the selector is incorrect; it is being given System.RunTimeType.

I have looked through the code a fair bit but unfortunately have no experience with code emitters so could not pinpoint the source, however the accepted answer on this SO question provides a good minimal reproduction of the issue.

proxying generic interface with inaccessible type parameters throws TypeLoadException

Consider this test:

internal interface InternalInterface
{
}

[Test]
public void CreateClassProxyType_PublicInterfaceWithInternalTypeParameter_ThrowsTypeLoadException()
{

    new DefaultProxyBuilder()
        .CreateClassProxyType(typeof (object),
                              new[] {typeof (IList<InternalInterface>)},
                              new ProxyGenerationOptions());
}

It results in the following error:

CreateClassProxyType_PublicInterfaceWithInternalTypeParameter_ThrowsGeneratorException : FailedSystem.TypeLoadException : Type 'Castle.Proxies.ObjectProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' is attempting to implement an inaccessible interface.
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateType()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type)
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
at CastleInaccessibleInterface.Tests.CreateClassProxyType_PublicInterfaceWithInternalTypeParameter_ThrowsGeneratorException() in Class1.cs: line 26

A novice user (or indeed someone indirectly using DynamicProxy, for example, via an isolation framework such as FakeItEasy or Moq), may be confused by this error message.

DynamicProxy goes to good lengths to intercept attempts to proxy what I'll call top-level types that aren't accessible (for example, if we were proxying InternalInterface directly, rather than an IList of them). Is there any interest in expanding the "bad request" detection to include inaccessible type parameters?

If so, I'd be happy to spend some time on it.

Fix problems using Xamarin Studio

When trying to build NET45-Debug or NET45-Release configurations from within Xamarin on Mac after opening Castle.Core.sln, these things have to be done for the build to be successful:

Add the missing project reference to Castle.Services.Logging.log4netIntegration to Castle.Core.Tests project
Disable the compiler setting of Treat warnings as errors for the Castle.Core.Tests project
But even after the solution starts building, the Unit Tests pad/pane within Xamarin does not show any of the tests within the solution.

All of these could be Xamarin Studio nuances - I haven't spent enough time yet on these.
(@floydpink)

The ValidateNotSameValueAttribute class ctor effectively ignors any Value type's parse method

At line 65 in ValidateNotSameValueAttribute.cs, the ctor for a value type is executed irrespective of whether or not a value was generated dynamically by the type's "Parse" method:

MethodBase createInstance = valueType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static);
if (createInstance != null)
{
    value = createInstance.Invoke(null, new object[] {mustNotBeThisValue});
}
ConstructorInfo ctor = valueType.GetConstructor(new Type[] {mustNotBeThisValue.GetType()});
if (ctor == null)
{
    // ...

A smiple fix would be to modify the above code so that the ctor is only used to generate a value if the parse method failed to do so, like so:

MethodBase createInstance = valueType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static);
if (createInstance != null)
{
    value = createInstance.Invoke(null, new object[] {mustNotBeThisValue});
}

if (value == null)
{
    ConstructorInfo ctor = valueType.GetConstructor(new Type[] {mustNotBeThisValue.GetType()});
    if (ctor == null)
    {
        // ...
}

Log warning if multiple ProxyGenerators/ModuleScope used

There should usually be only one (or few) ProxyGenerator (and more specifically ModuleScope) in an application.

A common misuse is to new up a ProxyGenerator every time a proxy type is needed which effectively is a memory leak, and a significant performance hit.

We should log a warning if multiple (more than 10 perhaps) are created, possibly even throw an exception, although this would be a breaking change, so perhaps logging will suffice.

Error creating an interface proxy in case the interface contains a method with an optional decimal parameter

Hello,

I have found an issue in Castle.Core 3.3.3 with the DynamicProxy generation. In case I want to create an interface proxy for an interface with an optional decimal parameter, the proxy generation fails with an 'System.Decimal is not a supported constant type' exception. The following program can be used to reproduce the issue:

class Program
{
  static void Main(string[] args)
  {
     var proxyGenerator = new ProxyGenerator();
     proxyGenerator.CreateInterfaceProxyWithoutTarget<IMyClass>(new StandardInterceptor());
  }
}

public interface IMyClass
{
  void Do(decimal d = 0m);
}

However, the exception only occurs with the Castle.Core build targeting the .NET Framework 4.5. The .NET Framework 4.0 build works fine. (I have not tested the 3.5 or Silverlight versions).

Here you can find the full stacktrace:

System.Reflection.Emit.TypeBuilder.SetConstantValue(ModuleBuilder module, Int32 tk, Type destType, Object value)
Castle.DynamicProxy.Generators.Emitters.MethodEmitter.DefineParameters(ParameterInfo[] parameters)
Castle.DynamicProxy.Generators.Emitters.MethodEmitter..ctor(AbstractTypeEmitter owner, String name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate)
Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateMethod(String name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate)
Castle.DynamicProxy.Generators.MethodGenerator.Generate(ClassEmitter class, ProxyGenerationOptions options, INamingScope namingScope)
Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementMethod(MetaMethod method, ClassEmitter class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod)
Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate(ClassEmitter class, ProxyGenerationOptions options)
Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.<>c__DisplayClass1.<GenerateCode>b__0(String n, INamingScope s)
Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, IInterceptor interceptor)
Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget[TInterface](IInterceptor interceptor)
ConsoleApplication.Program.Main(String[] args) in Program.cs:Zeile 12.
System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
System.Threading.ThreadHelper.ThreadStart()

Best regards,
Frederik

Silverlight 5 Support

When will support for SL 5 be added? External libraries like Moq seems stuck on SL4 until Castle.Core supports it. I'm willing to have a crack at trying to upgrade but are there breaking changes in SL5 that have prevented Castle.Core from being upgraded to SL5?

Parameterless Constructor not needed

When Creating a Proxy using CreateClassProxyWithTarget the Target must have a parameterless Constructor.
From my point of view, it would be easy sometimes, to be able to create a non initialized object, by calling
object newObject = FormatterServices.GetUninitializedObject(type);

protected object CreateClassProxyInstance(Type proxyType, List<object> proxyArguments, Type classToProxy, object[] constructorArguments)
{
  try
  {
      if (constructorArguments != null && constructorArguments.Length != 0)
        return Activator.CreateInstance(proxyType, proxyArguments.ToArray());

      foreach (var ctor in proxyType.GetConstructors())
        if (!ctor.GetParameters().Any())
          return Activator.CreateInstance(proxyType, proxyArguments.ToArray());

      return FormatterServices.GetUninitializedObject(proxyType)
  }
  catch (MissingMethodException ex)
  {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.AppendFormat("Can not instantiate proxy of class: {0}.", (object) classToProxy.FullName);
    stringBuilder.AppendLine();
    if (constructorArguments == null || constructorArguments.Length == 0)
    {
      stringBuilder.Append("Could not find a parameterless constructor.");
    }
    else
    {
      stringBuilder.AppendLine("Could not find a constructor that would match given arguments:");
      foreach (object obj in constructorArguments)
      {
        string str = obj == null ? "<null>" : obj.GetType().ToString();
        stringBuilder.AppendLine(str);
      }
    }
    throw new InvalidProxyConstructorArgumentsException(((object) stringBuilder).ToString(), proxyType, classToProxy);
  }
}

proxying generic interface with open generic type parameters throws vague ArgumentException

Found while writing characterization tests before starting on #34 proper.

Consider this test:

[Test]
public void Cannot_proxy_generic_type_with_open_generic_type_parameter()
{
    var innerType = typeof(IList<>);
    var targetType = innerType.MakeGenericType(typeof(IList<>));
    generator.CreateInterfaceProxyWithoutTarget(targetType, new IInterceptor[0]);
}

which corresponds to trying to proxy an IList<IList<>>.

It fails with

Test 'Castle.DynamicProxy.Tests.BasicInterfaceProxyTestCase.Cannot_proxy_generic_type_with_open_generic_type_parameter' failed:
    System.ArgumentException : Cannot build type parameter for custom attribute with a type that does not support the AssemblyQualifiedName property. The type instance supplied was of type 'System.RuntimeType'.

Compare this to the attempt to make proxy an IList<>, which returns an ArgumentException with the message

You can't specify a generic type definition.
Parameter name: interfaceToProxy

This is not a big deal for FakeItEasy, I don't think, and probably less of a problem overall than #34, but if there's interest, I can look into it alongside or after the fix for #34.

Memory Leak in DictionaryAdapterFactory.cs::CreateTypeBuilder() method

Hi,

Under namespace Castle.Components.DictionaryAdapter, DictionaryAdapterFactory.cs -

private static TypeBuilder CreateTypeBuilder(Type type, AppDomain appDomain)

There is a memory leak on this line -

var assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

It should be -

var assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect);

Can you please correct this?

You may also wish to check all other instances of the use of AssemblyBuilderAccess.Run and perhaps change them to AssemblyBuilderAccess.RunAndCollect?

Thanks,
Rodney

publish intermediate nuget packages

From a comment @kkozmic made on gitter, at 8:24 UTC on 18 May 2014. (Don't know how to link to a comment, and maybe they scroll away.)

@kkozmic and @jonorossi talked about publishing intermediate packages on the Castle TeamCity server. Later @kkozmic and I chatted about it. Mostly about how to label the packages. Options discussed (if I understand correctly)

  • including TeamCity build number as a component of the version
  • incorporating the git revision hash as a component, but this would mean the workers would have to know about git, which they currently do not

I don't know how TeamCity publishes NuGet packages, or how to add packages to its feed, but an alternative may be to push the packages to proper NuGet, only using prerelease versions to keep everyone from getting the builds. I think this is a nice idea, as

  • the builds would be more discoverable, and
  • someone else manages the storage (and/or cleanup)

A major downside is that to do this well, the release version number should be something like vNext.beta_xxx_, where vNext looks like the normal release numbers, e.g. 3.3.0, and the xxx is some continually increasing value, perhaps the TeamCity build number. The current Castle model is to not apply any vNext marker to a build until just before release. This obstacle may be enough to discount the "prerelease version on proper NuGet" option.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.