Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Castle.Core.Tests/BasicClassProxyTestCase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -87,7 +87,7 @@ public void ProxyForNonPublicClass()
var type = Type.GetType("System.AppDomainInitializerInfo, mscorlib");
var exception = Assert.Throws<GeneratorException>(() => generator.CreateClassProxy(type, new StandardInterceptor()));
Assert.AreEqual(
"Can not create proxy for type System.AppDomainInitializerInfo because it is not accessible. Make the type public, or internal and mark your assembly with [assembly: InternalsVisibleTo(\"DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7\")] attribute, because assembly mscorlib is strong-named.",
"Can not create proxy for type System.AppDomainInitializerInfo because it is not accessible. Make it public, or internal and mark your assembly with [assembly: InternalsVisibleTo(\"DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7\")] attribute, because assembly mscorlib is strong-named.",
exception.Message);
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/Castle.Core.Tests/BasicInterfaceProxyTestCase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -239,7 +239,7 @@ public void Cannot_proxy_generic_type_with_open_generic_type_parameter()
public void Cannot_proxy_inaccessible_interface()
{
var exception = Assert.Throws<GeneratorException>(() => generator.CreateInterfaceProxyWithoutTarget(typeof(PrivateInterface), new IInterceptor[0]));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.BasicInterfaceProxyTestCase+PrivateInterface because it is not accessible. Make the type public, or internal"));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.BasicInterfaceProxyTestCase+PrivateInterface because it is not accessible. Make it public, or internal"));
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -118,7 +118,7 @@ public void Cannot_proxy_generic_type_with_open_generic_type_parameter()
public void Cannot_proxy_inaccessible_class()
{
var exception = Assert.Throws<GeneratorException>(() => generator.CreateClassProxy(typeof(PrivateClass), new IInterceptor[0]));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.ClassProxyConstructorsTestCase+PrivateClass because it is not accessible. Make the type public, or internal"));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.ClassProxyConstructorsTestCase+PrivateClass because it is not accessible. Make it public, or internal"));
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -105,7 +105,7 @@ public void Can_proxy_purely_virtual_inherited_abstract_class()
public void Cannot_proxy_inaccessible_class()
{
var exception = Assert.Throws<GeneratorException>(() => generator.CreateClassProxyWithTarget<PrivateClass>(new PrivateClass()));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.ClassProxyWithTargetTestCase+PrivateClass because it is not accessible. Make the type public, or internal"));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.ClassProxyWithTargetTestCase+PrivateClass because it is not accessible. Make it public, or internal"));
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions src/Castle.Core.Tests/InterceptorSelectorTestCase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -293,7 +293,7 @@ public void Can_proxy_same_type_with_and_without_selector_InterfaceProxyWithTarg
public void Cannot_proxy_inaccessible_interface()
{
var exception = Assert.Throws<GeneratorException>(() => generator.CreateInterfaceProxyWithTarget<PrivateInterface>(new PrivateClass(), new IInterceptor[0]));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.InterceptorSelectorTestCase+PrivateInterface because it is not accessible. Make the type public, or internal"));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.InterceptorSelectorTestCase+PrivateInterface because it is not accessible. Make it public, or internal"));
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -184,7 +184,7 @@ public void ChangeProxyTarget_should_not_affect_invocation_target()
public void Cannot_proxy_inaccessible_interface()
{
var exception = Assert.Throws<GeneratorException>(() => generator.CreateInterfaceProxyWithTargetInterface<PrivateInterface>(new PrivateClass(), new IInterceptor[0]));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.InterfaceProxyWithTargetInterfaceTestCase+PrivateInterface because it is not accessible. Make the type public, or internal"));
Assert.That(exception.Message, Is.StringStarting("Can not create proxy for type Castle.DynamicProxy.Tests.InterfaceProxyWithTargetInterfaceTestCase+PrivateInterface because it is not accessible. Make it public, or internal"));
}

[Test]
Expand Down
4 changes: 3 additions & 1 deletion src/Castle.Core/Castle.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'MONO26-Debug|AnyCPU'">
<TargetFrameworkProfile>
</TargetFrameworkProfile>
Expand Down Expand Up @@ -367,7 +367,9 @@
<Compile Include="Components.DictionaryAdapter\Xml\Core\XmlMetadata.cs" />
<Compile Include="Components.DictionaryAdapter\Xml\Core\XmlMetadataBehavior.cs" />
<Compile Include="Core\Internal\CollectionExtensions.cs" />
<Compile Include="Core\Internal\ExceptionMessageBuilder .cs" />
<Compile Include="Core\Internal\InterfaceAttributeUtil.cs" />
<Compile Include="Core\Internal\TypeExtensions.cs" />
<Compile Include="Core\Internal\WeakKey.cs" />
<Compile Include="Core\Internal\WeakKeyComparer.cs" />
<Compile Include="Core\Internal\WeakKeyDictionary.cs" />
Expand Down
94 changes: 94 additions & 0 deletions src/Castle.Core/Core/Internal/ExceptionMessageBuilder .cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Castle.Core.Internal
{
using System;
using System.Linq;
using System.Reflection;
using Castle.DynamicProxy.Generators.Emitters;

internal static class ExceptionMessageBuilder
{
/// <summary>
/// Creates a message to inform clients that a proxy couldn't be created due to reliance on an
/// inaccessible type (perhaps itself).
/// </summary>
/// <param name="inaccessibleType">the inaccessible type that prevents proxy creation</param>
/// <param name="typeToProxy">the type that couldn't be proxied</param>
public static string CreateMessageForInaccessibleType(Type inaccessibleType, Type typeToProxy)
{
var targetAssembly = typeToProxy.Assembly;

string strongNamedOrNotIndicator = " not"; // assume not strong-named
string assemblyToBeVisibleTo = "\"DynamicProxyGenAssembly2\""; // appropriate for non-strong-named

if (targetAssembly.IsAssemblySigned())
{
strongNamedOrNotIndicator = "";
assemblyToBeVisibleTo = ReferencesCastleCore(targetAssembly)
? assemblyToBeVisibleTo = "InternalsVisible.ToDynamicProxyGenAssembly2"
: assemblyToBeVisibleTo = '"' + InternalsVisible.ToDynamicProxyGenAssembly2 + '"';
}

string inaccessibleTypeDescription = inaccessibleType == typeToProxy
? "it"
: "type " + inaccessibleType.GetBestName();

var messageFormat =
"Can not create proxy for type {0} because {1} is not accessible. " +
"Make it public, or internal and mark your assembly with " +
"[assembly: InternalsVisibleTo({2})] attribute, because assembly {3} " +
"is{4} strong-named.";

return string.Format(messageFormat,
typeToProxy.GetBestName(),
inaccessibleTypeDescription,
assemblyToBeVisibleTo,
GetAssemblyName(targetAssembly),
strongNamedOrNotIndicator);
}

private static string GetAssemblyName(Assembly targetAssembly)
{
#if SILVERLIGHT
// SILVERLIGHT doesn't allow us to call assembly.GetName()
var fullName = targetAssembly.FullName;
if (string.IsNullOrEmpty(fullName))
{
return fullName;
}
var index = fullName.IndexOf(", Version=", StringComparison.OrdinalIgnoreCase);
if (index > 0)
{
return fullName.Substring(0, index);
}
return fullName;
#else
return targetAssembly.GetName().Name;
#endif
}

private static bool ReferencesCastleCore(Assembly inspectedAssembly)
{
#if SILVERLIGHT
// no way to check that in SILVERLIGHT, so we just fall back to the solution that will definitely work
return false;
#else
return inspectedAssembly.GetReferencedAssemblies()
.Any(r => r.FullName == Assembly.GetExecutingAssembly().FullName);
#endif
}
}
}
36 changes: 36 additions & 0 deletions src/Castle.Core/Core/Internal/TypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Castle.Core.Internal
{
using System;

internal static class TypeExtensions
{
/// <summary>
/// Find the best available name to describe a type.
/// </summary>
/// <remarks>
/// Usually the best name will be <see cref="Type.FullName"/>, but
/// sometimes that's null (see http://msdn.microsoft.com/en-us/library/system.type.fullname%28v=vs.110%29.aspx)
/// in which case the method falls back to <see cref="Type.Name"/>.
/// </remarks>
/// <param name="type">the type to name</param>
/// <returns>the best name</returns>
public static string GetBestName(this Type type)
{
return type.FullName ?? type.Name;
}
}
}
75 changes: 3 additions & 72 deletions src/Castle.Core/DynamicProxy/DefaultProxyBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -122,11 +122,11 @@ private void AssertValidTypeForTarget(Type type, Type target)
if (type.IsGenericTypeDefinition)
{
throw new GeneratorException(string.Format("Can not create proxy for type {0} because type {1} is an open generic type.",
target.FullName ?? target.Name, type.FullName ?? target.Name));
target.GetBestName(), type.GetBestName()));
}
if (IsPublic(type) == false && IsAccessible(type) == false)
{
throw new GeneratorException(BuildInternalsVisibleMessageForType(type, target));
throw new GeneratorException(ExceptionMessageBuilder.CreateMessageForInaccessibleType(type, target));
}
foreach (var typeArgument in type.GetGenericArguments())
{
Expand Down Expand Up @@ -163,74 +163,5 @@ private static bool IsInternal(Type target)

return isInternalNotNested || isNestedAndInternal;
}

private static string BuildInternalsVisibleMessageForType(Type type, Type target)
{
var targetAssembly = target.Assembly;

string strongNamedOrNotIndicator = " not"; // assume not strong-named
string assemblyToBeVisibleTo = "\"DynamicProxyGenAssembly2\""; // appropriate for non-strong-named

if (targetAssembly.IsAssemblySigned())
{
strongNamedOrNotIndicator = "";
if (ReferencesCastleCore(targetAssembly))
{
assemblyToBeVisibleTo = "InternalsVisible.ToDynamicProxyGenAssembly2";
}
else
{
assemblyToBeVisibleTo = '"' + InternalsVisible.ToDynamicProxyGenAssembly2 + '"';
}
}

var messageFormat = type == target
? "Can not create proxy for type {0} " +
"because it is not accessible. " +
"Make the type public, or internal and mark your assembly with " +
"[assembly: InternalsVisibleTo({2})] attribute, because assembly {3} " +
"is{4} strong-named."
: "Can not create proxy for type {0} " +
"because type {1} is not accessible. " +
"Make it public, or internal and mark your assembly with " +
"[assembly: InternalsVisibleTo({2})] attribute, because assembly {3} " +
"is{4} strong-named.";
return string.Format(messageFormat,
target.FullName ?? target.Name, type.FullName ?? target.Name, assemblyToBeVisibleTo,
#if SILVERLIGHT
//SILVERLIGHT is retarded and doesn't allow us to call assembly.GetName()
GetAssemblyName(targetAssembly),
#else
targetAssembly.GetName().Name,
#endif
strongNamedOrNotIndicator);
}

#if SILVERLIGHT
private static string GetAssemblyName(Assembly targetAssembly)
{
var fullName = targetAssembly.FullName;
if (string.IsNullOrEmpty(fullName))
{
return fullName;
}
var index = fullName.IndexOf(", Version=", StringComparison.OrdinalIgnoreCase);
if (index > 0)
{
return fullName.Substring(0, index);
}
return fullName;
}
#endif
private static bool ReferencesCastleCore(Assembly inspectedAssembly)
{
#if SILVERLIGHT
// no way to check that in SILVELIGHT, so we just fall back to the solution that will definitely work
return false;
#else
return inspectedAssembly.GetReferencedAssemblies()
.Any(r => r.FullName == Assembly.GetExecutingAssembly().FullName);
#endif
}
}
}
4 changes: 2 additions & 2 deletions src/Castle.Core/DynamicProxy/ProxyGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2004-2013 Castle Project - http://www.castleproject.org/
// Copyright 2004-2014 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -1487,7 +1487,7 @@ protected void CheckNotGenericTypeDefinition(Type type, string argumentName)
if (type != null && type.IsGenericTypeDefinition)
{
throw new GeneratorException(string.Format("Can not create proxy for type {0} because it is an open generic type.",
type.FullName ?? type.Name));
type.GetBestName()));
}
}

Expand Down