WCF and IEndpointBehavior

611 views
Skip to first unread message

Phillip Haydon

unread,
Nov 2, 2011, 8:37:58 PM11/2/11
to Autofac
Hey,

I'm trying to apply a Unit Of Work similar to what's described here:

http://ianfnelson.com/archives/2010/04/09/wcf-nhibernate-unit-of-work-endpoint-behavior

Since I can't find any other ways to do it. How can I achieve this
with Autofac, and is there a better way of doing it?

Travis Illig

unread,
Nov 3, 2011, 12:50:32 PM11/3/11
to aut...@googlegroups.com
To the best of my knowledge, Autofac doesn't have a feature to do DI into endpoint behaviors, so you'd have to resolve the dependency manually. (Nick will, I'm sure, jump in here and correct me if I'm wrong.) So in your behavior where you need your IUnitOfWork as a constructor parameter, you'd instead resolve it directly:

public UnitOfWorkEndpointBehavior()
{
  this.unitOfWork = AutofacHostFactory.Container.Resolve<IUnitOfWork>();
}

You can still apply behaviors through XML configuration using Autofac, just like normal, but if you want to do it programmatically you can have a custom host factory based on AutofacServiceHostFactory and use the ConfigurationAction static property

UnitOfWorkAutofacHostFactory.ConfigurationAction =
  host =>
    host.Opening += (sender, args) =>
      host.Description.Behaviors.Add(new UnitOfWorkEndpointBehavior());

Then specify the custom UnitOfWorkAutofacHostFactory in your .svc file as the service host factory.

Phillip Haydon

unread,
Nov 3, 2011, 9:10:46 PM11/3/11
to Autofac
Hmm, The Behaviors takes in IServiceBehavior rather than
IEndpointBehavior

If I set it up to use a ServiceBehavior it get's injected once, and
never again, I guess that the service behavior is newed up once?

The same thing happens with the EndPointBehavior.

I stepped through all the code and it seems that the
CallContextInitializer is created once, and BeforeInvoke/AfterInvoke
are called every request, so I would need to pass a IContainer down to
the CallContextInitializer and resolve a new IUnitOfWork BeforeInvoke
and commit it AfterInvoke.

What has confused me is the article relies on the fact that the
UnitOfWork is created once, and it's role is simply to Open a NH
Session and Transaction, and Commit it later.

I want a new UnitOfWork created for each request which wasn't
happening.

I think I've solved my problem, it's a little bit work, will have to
write my own ServiceBehavior, EndpointBehavior, and
CallContextInitializer, and pass the Autofac IContainer in for it to
resolve the UnitOfWork, but it will do what I want it to do :)

Phillip Haydon

unread,
Nov 3, 2011, 11:47:18 PM11/3/11
to Autofac
Nope, no luck, passing in the IContainerContext or ILifetimeContext
and resolving the Unit of Work:

public object BeforeInvoke(InstanceContext instanceContext,
IClientChannel channel, Message message)
{
var uow = _container.Resolve<IUnitOfWork>();

uow.Begin();

return null;
}

public void AfterInvoke(object correlationState)
{
var uow = _container.Resolve<IUnitOfWork>();

uow.Commit();
}

Causes two different instances to be returned. They aren't in the same
scope. :(

builder.RegisterType(typeof (UnitOfWork))
.As(typeof (IUnitOfWork))
.InstancePerLifetimeScope()
.OnRelease(x =>
{
((IUnitOfWork) x).Commit();
});

This however, seems to work fine. But seems real hacky...

Phillip Haydon

unread,
Nov 5, 2011, 11:23:47 AM11/5/11
to Autofac
I've posted my current solution here if anyone cares :)

http://www.philliphaydon.com/2011/11/unit-of-work-with-wcf-and-autofac/

If anyone has any feedback on it, would be appreciated.

Nicholas Blumhardt

unread,
Nov 6, 2011, 9:21:26 PM11/6/11
to aut...@googlegroups.com
Hi Phillip - thanks for the follow up, glad you were able to sort something out.

Nick

--
You received this message because you are subscribed to the Google Groups "Autofac" group.
To post to this group, send email to aut...@googlegroups.com.
To unsubscribe from this group, send email to autofac+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/autofac?hl=en.


Phillip Haydon

unread,
Nov 7, 2011, 12:28:08 AM11/7/11
to Autofac
Hey Nick,

I've sort of decided to just use my UoW like:

using (UnitOfWork)
{
}

In my service, because unlike MVC I can't find a good spot in WCF to
capture an exception and roll the transaction back. So without
manually capturing all exceptions in code I don't feel it's a
bulletproof solution yet :(

I'm going to have another play this weekend, see if I can find a good
way of being able to roll the transaction back on exception.

Cheers.

Phill

On Nov 7, 1:21 pm, Nicholas Blumhardt <nicholas.blumha...@gmail.com>
wrote:
> Hi Phillip - thanks for the follow up, glad you were able to sort something
> out.
>
> Nick
>

karampel...@gmail.com

unread,
Mar 20, 2012, 2:39:50 AM3/20/12
to aut...@googlegroups.com
Hi Nick,

I think this is an interesting feature for adding into Autofac.WcfIntegration, that is the ability to have Autofac handle the creation of EndPointBehaviors. I don't know if it is doable and if WCF provides the wiring for that, but it sure would be useful... Are there any plans for it?

Btw, and since this is my first time posting here, great job on Autofac, absolutely loving it.

Thanks,
Kostas

Nicholas Blumhardt

unread,
Mar 25, 2012, 11:13:15 PM3/25/12
to aut...@googlegroups.com
Thanks Kostas. No current plans I'm aware of, but others on this list who spend more time with WCF may have some thoughts here.

Cheers!
Nick

--
You received this message because you are subscribed to the Google Groups "Autofac" group.
To view this discussion on the web visit https://groups.google.com/d/msg/autofac/-/POvGWPCUtpEJ.

Alex Meyer-Gleaves

unread,
Mar 26, 2012, 10:07:51 AM3/26/12
to aut...@googlegroups.com

Hi Kostas,

 

In the case of self-hosting you have to add the endpoint behaviors to the Behaviors collection on the service endpoint before opening the service host, so you could resolve any instances of IEndpointBehavior from the container and add them before opening the host manually. For IIS hosting, we could resolve the behaviors from the container for you and add them before opening the service host. Do you have a particular scenario in mind?

 

Cheers,

 

Alex.

Reply all
Reply to author
Forward
0 new messages