Search code examples
c#wcfdependency-injectionautofacremoting

Autofac fails to initailly resolve object from remote assembly (cast to know type)


Here is my WCF(vs2015@net452) autofac (v4.6.1) setup:

MyService.dll:

builder.Register(c => (ISession)RemoteObjectFactory.GetInstance(typeof(MySessionBase))).As<ISession>().SingleInstance();
...
var session = AutofacHostFactory.Container.Resolve<ISession>();

<Message>An exception was thrown while executing a resolve operation. See the InnerException for details.
Could not load file or assembly "MyRemotingHost, Version=1.0.6442.29085, Culture=neutral, PublicKeyToken=null" or one of its dependencies. File not found(See inner exception for details.)</Message>
<StackTrace>at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)&#xD;
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object&amp; instance)&#xD;
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)&#xD;
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)&#xD;
at My.DoSomeWork() at C:\Projects\...
<Type>Autofac.Core.DependencyResolutionException</Type>

MyService.dll refers to MyDefs.dll.

MyRemotingHost.dll refers to MyDefs.dll.

MyService.dll calls MyRemotingHost.dll via remoting. RemoteObjectFactory.GetInstance is a wrapper method that returns(via remoting) Transparent Proxy to MySession object from MyRemotingHost.dll.

Abstract class MySessionBase implements ISession. Both are defined in MyDefs.dll.

Class MySession is a sublcass of MySessionBase and is defined in MyRemotingHost.dll.

Strictly speaking MyService.dll does not know about MyRemotingHost.dll and should not know about it. Why then autofac tries to get information about this assembly which is remote??

Update

ISession session = (MySessionBase)RemoteObjectFactory.GetInstance(typeof(MySessionBase));
builder.RegisterInstance(session);

RegisterInstance throws same error.

Update2 Second(and subsequent) resolution attempts do not throw error which is weird.

builder.Register(c => (ISession)RemoteObjectFactory.GetInstance(typeof(MySessionBase))).As<ISession>().SingleInstance();
...
var session1 = AutofacHostFactory.Container.Resolve<ISession>();
var session2 = AutofacHostFactory.Container.Resolve<ISession>();

Line var session1 = ... throws error. If error is suppressed, then next line var session2 = ... DOES NOT produce error.

PDB-based step-by-step debugging shows that error source is at Autofac.Core.Resolving.ResolveOperation inside foreach loop at the 1st call to enumerator:

private void CompleteActivations()
{
    var completed = _successfulActivations;
    ResetSuccessfulActivations();

    foreach (var activation in completed)
        activation.Complete();
}

I cannot investigate more as I am stuck to VS2015 while autofac sources have VS2017 format already.


Solution

  • The problem was in the log4net autofac module:

    var instanceType = instance.GetType();
    

    Adding checks before that line solves the problem:

    // cant use GetType() on TransparentProxy as it may throw error
    if (RemotingServices.IsTransparentProxy(instance)) return;