Search code examples
c#dependency-injectionautofaccastle-dynamicproxy

Autofac.Extras.DynamicProxy got error with public interface


I have public interface and internal impl,

public interface IService
{
    ...
}
internal class Service: IService
{
    ...
}

I registered them via

builder.RegisterAssemblyTypes(assembly)
       .EnableInterfaceInterceptors()
       .AsImplementedInterfaces()
       .AsSelf()

But I'm getting error

The component Activator = Service (ReflectionActivator), Services = [~.IService, ~.Service], Lifetime = Autofac.Core.Lifetime.MatchingScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope cannot use interface interception as it provides services that are not publicly visible interfaces. Check your registration of the component to ensure you're not enabling interception and registering it as an internal/private interface type.

Why am I getting this error? My interface is public.


Solution

  • When using the AsSelf() method, the container will add the concrete type in the service list of the current registration.

    The error message is

    cannot use interface interception as it provides services that are not publicly visible interface

    It means that all services of the registration should be an interface which is not the case. You can see it in the EnsureInterfaceInterceptionApplies method

    private static void EnsureInterfaceInterceptionApplies(IComponentRegistration componentRegistration)
    {
        if (componentRegistration.Services
            .OfType<IServiceWithType>()
            .Select(s => new Tuple<Type, TypeInfo>(s.ServiceType, s.ServiceType.GetTypeInfo()))
            .Any(s => !s.Item2.IsInterface || !ProxyUtil.IsAccessible(s.Item1)))
        {
            throw new InvalidOperationException(
                string.Format(
                    CultureInfo.CurrentCulture,
                    RegistrationExtensionsResources.InterfaceProxyingOnlySupportsInterfaceServices,
                    componentRegistration));
        }
    }
    

    If you remove the .AsSelf() call, the code will work.