Using a Custom Endpoint Behavior with WCF and Autofac

拟墨画扇 提交于 2019-12-06 02:31:06

问题


I'm trying to implement a UoW like shown here: http://blog.iannelson.systems/wcf-global-exception-handling/

But I can't for the life of me figure out how to wire it up with Autofac. I have absolutely no idea where to start.

I've got WCF working fine with Autofac from using http://autofac.readthedocs.org/en/latest/integration/wcf.html

But to inject or add the IEndpointBehavior? No idea...

If there's a better way to implement a UoW I would like to hear.

Edit:

For now I've just done:

builder.RegisterType(typeof (UnitOfWork))
    .As(typeof (IUnitOfWork))
    .InstancePerLifetimeScope()
    .OnRelease(x =>
    {
        Trace.WriteLine("Comitted of UoW");
        ((IUnitOfWork) x).Commit();
        // OnRelease inhibits the default Autofac Auto-Dispose behavior so explicitly chain to it
        x.Dispose(); 
    });

Though I don't know if this is an acceptable way of doing it, seems like a hack :(

Edit2:

Doesn't seem like it's possible to run a UoW in WCF :/

Edit 3:

I've posted my solution here: http://www.philliphaydon.com/2011/11/06/unit-of-work-with-wcf-and-autofac/


回答1:


I have found a solution to this problem, where the unit of work only will be committed if no errors is thrown.

Register the unit of work as InstancePerLifetimeScope in Autofac

    builder.RegisterType(typeof (UnitOfWork))
    .As(typeof (IUnitOfWork)).InstancePerLifetimeScope();

Then i have created a combined EndpointBehavior and a ErrorHandler.

public class UnitOfWorkEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        var unitOfWorkInstanceHandler = new UnitOfWorkInstanceHandler();

        endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(unitOfWorkInstanceHandler);
        endpointDispatcher.DispatchRuntime.InstanceContextInitializers.Add(unitOfWorkInstanceHandler);
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    protected override object CreateBehavior()
    {
        return new UnitOfWorkEndpointBehavior();
    }

    public override Type BehaviorType
    {
        get { return typeof (UnitOfWorkEndpointBehavior); }
    }
}



public class UnitOfWorkInstanceHandler : IInstanceContextInitializer, IErrorHandler
{
    private bool _doCommit = true;

    public void Initialize(InstanceContext instanceContext, Message message)
    {
        instanceContext.Closing += CommitUnitOfWork;
    }

    void CommitUnitOfWork(object sender, EventArgs e)
    {
        //Only commit if no error has occured
        if (_doCommit)
        {
            //Resolve the UnitOfWork form scope in Autofac
            OperationContext.Current.InstanceContext.Extensions.Find<AutofacInstanceContext>().Resolve<IUnitOfWork>().Commit();
        }
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        _doCommit = false;
    }

    public bool HandleError(Exception error)
    {
        _doCommit = false;
        return false;
    }
}

The registration of the Endpoint Behavior in web.config

<system.serviceModel>
    ...
    <extensions>
      <behaviorExtensions>
        <add name="UnitOfWork" type="Namespace.UnitOfWorkBehavior, Namespace"/>
      </behaviorExtensions>
    </extensions>
      <behaviors>
        <endpointBehaviors>
          <behavior name="">
            <UnitOfWork/>
          </behavior>
        </endpointBehaviors>
    ...
    </behaviors>
    ...
</system.serviceModel>


来源:https://stackoverflow.com/questions/7989918/using-a-custom-endpoint-behavior-with-wcf-and-autofac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!