Skip to content

Commit

Permalink
Updated to handle changes in reflection for netstandard.
Browse files Browse the repository at this point in the history
Travis Illig committed Jan 26, 2017
1 parent 392b056 commit 75360d3
Showing 9 changed files with 72 additions and 40 deletions.
2 changes: 1 addition & 1 deletion build.ps1
Original file line number Diff line number Diff line change
@@ -23,6 +23,6 @@ Get-DotNetProjectDirectory -RootPath $PSScriptRoot | Restore-DependencyPackages
Get-DotNetProjectDirectory -RootPath $PSScriptRoot\src | Invoke-DotNetPack -PackagesPath $packagesPath

# Test
Get-DotNetProjectDirectory -RootPath $PSScriptRoot\test | Invoke-Test
Get-DotNetProjectDirectory -RootPath $PSScriptRoot\test | Where-Object { $_ -inotlike "*Autofac.Extras.DynamicProxy.Test.SatelliteAssembly" } | Invoke-Test

Pop-Location
62 changes: 42 additions & 20 deletions src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs
Original file line number Diff line number Diff line change
@@ -27,13 +27,17 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Remoting;
using System.Reflection;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Features.Scanning;
using Castle.DynamicProxy;
using Castle.DynamicProxy.Internal;

#if NET45
using System.Runtime.Remoting;
#endif

namespace Autofac.Extras.DynamicProxy
{
/// <summary>
@@ -68,8 +72,8 @@ public static IRegistrationBuilder<TLimit, ScanningActivatorData, TRegistrationS
/// Only virtual methods can be intercepted this way.
/// </summary>
/// <typeparam name="TLimit">Registration limit type.</typeparam>
/// <typeparam name="TRegistrationStyle">Registration style.</typeparam>
/// <typeparam name="TConcreteReflectionActivatorData">Activator data type.</typeparam>
/// <typeparam name="TRegistrationStyle">Registration style.</typeparam>
/// <param name="registration">Registration to apply interception to.</param>
/// <returns>Registration builder allowing the registration to be configured.</returns>
public static IRegistrationBuilder<TLimit, TConcreteReflectionActivatorData, TRegistrationStyle> EnableClassInterceptors<TLimit, TConcreteReflectionActivatorData, TRegistrationStyle>(
@@ -110,8 +114,8 @@ public static IRegistrationBuilder<TLimit, ScanningActivatorData, TRegistrationS
/// Only virtual methods can be intercepted this way.
/// </summary>
/// <typeparam name="TLimit">Registration limit type.</typeparam>
/// <typeparam name="TRegistrationStyle">Registration style.</typeparam>
/// <typeparam name="TConcreteReflectionActivatorData">Activator data type.</typeparam>
/// <typeparam name="TRegistrationStyle">Registration style.</typeparam>
/// <param name="registration">Registration to apply interception to.</param>
/// <param name="options">Proxy generation options to apply.</param>
/// <param name="additionalInterfaces">Additional interface types. Calls to their members will be proxied as well.</param>
@@ -129,7 +133,8 @@ public static IRegistrationBuilder<TLimit, TConcreteReflectionActivatorData, TRe

registration.ActivatorData.ImplementationType =
ProxyGenerator.ProxyBuilder.CreateClassProxyType(
registration.ActivatorData.ImplementationType, additionalInterfaces ?? new Type[0],
registration.ActivatorData.ImplementationType,
additionalInterfaces ?? new Type[0],
options);

registration.OnPreparing(e =>
@@ -198,8 +203,16 @@ public static IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationSt
{
EnsureInterfaceInterceptionApplies(e.Component);

var proxiedInterfaces = e.Instance.GetType().GetInterfaces()
.Where(i => i.IsVisible || i.Assembly.IsInternalToDynamicProxy()).ToArray();
var proxiedInterfaces =
e.Instance
.GetType()
.GetInterfaces()
.Where(i =>
{
var ti = i.GetTypeInfo();
return ti.IsVisible || ti.Assembly.IsInternalToDynamicProxy();
})
.ToArray();

if (!proxiedInterfaces.Any())
{
@@ -304,6 +317,7 @@ public static IRegistrationBuilder<TLimit, TActivatorData, TStyle> InterceptedBy
return InterceptedBy(builder, interceptorServiceTypes.Select(t => new TypedService(t)).ToArray());
}

#if NET45
/// <summary>
/// Intercepts the interface of a transparent proxy (such as WCF channel factory based clients).
/// </summary>
@@ -346,8 +360,9 @@ public static IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationSt
throw new DependencyResolutionException(string.Format(
CultureInfo.CurrentCulture, RegistrationExtensionsResources.TypeIsNotTransparentProxy, e.Instance.GetType().FullName));
}

if (!e.Instance.GetType().IsInterface)
var instanceType = e.Instance.GetType();
var instanceTypeInfo = instanceType.GetTypeInfo();
if (!instanceTypeInfo.IsInterface)
{
throw new DependencyResolutionException(string.Format(
CultureInfo.CurrentCulture, RegistrationExtensionsResources.TransparentProxyIsNotInterface, e.Instance.GetType().FullName));
@@ -363,34 +378,40 @@ public static IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationSt

if (invalidInterfaces.Any())
{
string message = string.Format(CultureInfo.CurrentCulture, RegistrationExtensionsResources.InterfaceNotSupportedByTransparentProxy,
string.Join(", ", invalidInterfaces.Select(i => i.FullName)));
string message = string.Format(
CultureInfo.CurrentCulture,
RegistrationExtensionsResources.InterfaceNotSupportedByTransparentProxy,
string.Join(", ", invalidInterfaces.Select(i => i.FullName)));
throw new DependencyResolutionException(message);
}
}

var interceptors = GetInterceptorServices(e.Component, e.Instance.GetType())
var interceptors = GetInterceptorServices(e.Component, instanceType)
.Select(s => e.Context.ResolveService(s))
.Cast<IInterceptor>()
.ToArray();

e.Instance = options == null
? ProxyGenerator.CreateInterfaceProxyWithTargetInterface(e.Instance.GetType(), additionalInterfacesToProxy, e.Instance, interceptors)
: ProxyGenerator.CreateInterfaceProxyWithTargetInterface(e.Instance.GetType(), additionalInterfacesToProxy, e.Instance, options, interceptors);
? ProxyGenerator.CreateInterfaceProxyWithTargetInterface(instanceType, additionalInterfacesToProxy, e.Instance, interceptors)
: ProxyGenerator.CreateInterfaceProxyWithTargetInterface(instanceType, additionalInterfacesToProxy, e.Instance, options, interceptors);
});

return registration;
}
#endif

private static void EnsureInterfaceInterceptionApplies(IComponentRegistration componentRegistration)
{
if (componentRegistration.Services
.OfType<IServiceWithType>()
.Any(swt => !swt.ServiceType.IsInterface || (!swt.ServiceType.Assembly.IsInternalToDynamicProxy() && !swt.ServiceType.IsVisible)))
.Select(s => s.ServiceType.GetTypeInfo())
.Any(s => !s.IsInterface || (!s.Assembly.IsInternalToDynamicProxy() && !s.IsVisible)))
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
RegistrationExtensionsResources.InterfaceProxyingOnlySupportsInterfaceServices,
componentRegistration));
throw new InvalidOperationException(
string.Format(
CultureInfo.CurrentCulture,
RegistrationExtensionsResources.InterfaceProxyingOnlySupportsInterfaceServices,
componentRegistration));
}
}

@@ -414,16 +435,17 @@ private static IEnumerable<Service> GetInterceptorServices(IComponentRegistratio
result = result.Concat((IEnumerable<Service>)services);
}

if (implType.IsClass)
var implTypeInfo = implType.GetTypeInfo();
if (implTypeInfo.IsClass)
{
result = result.Concat(implType
result = result.Concat(implTypeInfo
.GetCustomAttributes(typeof(InterceptAttribute), true)
.Cast<InterceptAttribute>()
.Select(att => att.InterceptorService));

result = result.Concat(implType
.GetInterfaces()
.SelectMany(i => i.GetCustomAttributes(typeof(InterceptAttribute), true))
.SelectMany(i => i.GetTypeInfo().GetCustomAttributes(typeof(InterceptAttribute), true))
.Cast<InterceptAttribute>()
.Select(att => att.InterceptorService));
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -6,9 +6,6 @@
"keyFile": "../../Autofac.snk"
},
"dependencies": {
"Autofac": {
"target": "project"
},
"NETStandard.Library": "1.6.0",
"StyleCop.Analyzers": {
"type": "build",
Original file line number Diff line number Diff line change
@@ -175,6 +175,7 @@ public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IIntercep
{
throw new InvalidOperationException("No interceptors for method " + method.Name);
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
#if NET46
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using Autofac.Core;
@@ -106,6 +107,7 @@ private static ServiceHost CreateTestServiceHost(ILifetimeScope container)
{
var host = new ServiceHost(typeof(TestService), TestServiceAddress);
host.AddServiceEndpoint(typeof(ITestService), new BasicHttpBinding(), "");

// host.AddDependencyInjectionBehavior<ITestService>(container);
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true, HttpGetUrl = TestServiceAddress });
return host;
@@ -135,3 +137,4 @@ public void Intercept(IInvocation invocation)
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
#if NET46
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -173,6 +174,7 @@ private static ServiceHost CreateTestServiceHost(ILifetimeScope container)
{
var host = new ServiceHost(typeof(TestService), TestServiceAddress);
host.AddServiceEndpoint(typeof(ITestService), new BasicHttpBinding(), "");

// host.AddDependencyInjectionBehavior<ITestService>(container);
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true, HttpGetUrl = TestServiceAddress });
return host;
@@ -239,3 +241,4 @@ public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IIntercep
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using Autofac.Extras.DynamicProxy.Test.SatelliteAssembly;
using Castle.Core.Internal;
@@ -22,7 +23,7 @@ internal interface IInternalInterface
[Fact]
public void InterceptsInternalInterfacesWithInternalsVisibleToDynamicProxyGenAssembly2()
{
var internalsAttribute = typeof(InterfaceInterceptorsFixture).Assembly.GetAttribute<InternalsVisibleToAttribute>();
var internalsAttribute = typeof(InterfaceInterceptorsFixture).GetTypeInfo().Assembly.GetCustomAttribute<InternalsVisibleToAttribute>();
Assert.Contains("DynamicProxyGenAssembly2", internalsAttribute.AssemblyName);

var builder = new ContainerBuilder();
6 changes: 5 additions & 1 deletion test/Autofac.Extras.DynamicProxy.Test/project.json
Original file line number Diff line number Diff line change
@@ -28,7 +28,11 @@
}
}
},
"net46": { }
"net46": {
"frameworkAssemblies": {
"System.ServiceModel": "4.0.0.0"
}
}
},
"testRunner": "xunit"
}

0 comments on commit 75360d3

Please sign in to comment.