Using AutofacServiceHostFactory on a non-HTTP Activation WCF service

615 views
Skip to first unread message

Josh

unread,
Apr 9, 2010, 3:41:43 PM4/9/10
to Autofac
I have a set of WCF services that all use the
Autofac.Integration.Wcf.AutofacServiceHostFactory.

All my registrations are happening in the Application_Start() event on
the global.
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.RegisterType<MembershipService>().InstancePerDependency();

builder.RegisterType<Logic.MembershipLogic>().As<IMembershipLogic>().InstancePerLifetimeScope();
AutofacHostFactory.Container = builder.Build();
}

All is happy when using a binding that uses HTTP Activation. Then I
tried to switch over to net.tcp, and none of the events in the
Global.asax fire.

What is the best/least painful/standard/etc way to initialize Autofac
when using WAS/non-HTTP activation WCF services? I've seen posts
suggesting AppInitialize(), but those are pretty ugly.

Thanks,
Josh

Matt Burton

unread,
Apr 9, 2010, 3:47:39 PM4/9/10
to aut...@googlegroups.com
To the best of my knowledge the AppInitialize method is the only way
to do it right now. When I was doing spikes way back when, what I
wound up doing was putting a c# file in App_Code that would call out
to a bootstrapper class inside the AppInitialize method, so at least
you keep the amount of code in there to a minimum. It's really
unfortunate. I don't know if the ability to hook into the Application
start event in IIS 7.5 / ASP.NET 4.0 changes things or not - if you
can target that platform it might be worth investigating.

> --
> 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.
>
>

Josh

unread,
Apr 9, 2010, 3:58:18 PM4/9/10
to Autofac
We are targeting that platform, but I'm not sure what you mean. How
can you hook into those events?

Matt Burton

unread,
Apr 9, 2010, 4:15:13 PM4/9/10
to aut...@googlegroups.com
Good deal - so with .NET 4.0 / IIS 7.5 you can hook into the event
that gets raised when an application pool starts up - the original
intent was to give your application a hook to pre-load caches before
any requests come in so you can avoid the whole "it's slow for the
first user but fast for the rest" syndrome. More details here:

http://www.asp.net/LEARN/whitepapers/aspnet4/default.aspx#_TOC1_3

If you don't want to write any code there is a module that you can
install that will do this for you:

http://www.iis.net/download/applicationwarmup

Just feed it some URL's to hit when the app pool comes up and you're
good to go. In the case of a non-HTTP activation WCF / WAS scenario
you might consider having a "ping" page in the application you deploy
under IIS that you configure the module to hit...just thinking out
loud...

Please let me know how it works out for you if you decide to make use
of this approach (code for the event or the module) - would love to
know myself! :)

felix

unread,
Jun 7, 2010, 2:09:17 PM6/7/10
to Autofac
I think that the problem is the same described here
http://blog.ploeh.dk/2010/05/18/SneakViewAtCastlesWCFFacility.aspx
from MarkSeemann.
And probably the solution is of the same type.
Is possible to insert an example of this configuration without
global.asax in the wiki page of wcf or better add something in
Autofac.Integration.Wcf to enable this type of requirment?

Thanks,
Felix

On Apr 9, 10:15 pm, Matt Burton <matt.bur...@gmail.com> wrote:
> Good deal - so with .NET 4.0 / IIS 7.5 you can hook into the event
> that gets raised when an application pool starts up - the original
> intent was to give your application a hook to pre-load caches before
> any requests come in so you can avoid the whole "it's slow for the
> first user but fast for the rest" syndrome. More details here:
>
> http://www.asp.net/LEARN/whitepapers/aspnet4/default.aspx#_TOC1_3
>
> If you don't want to write any code there is a module that you can
> install that will do this for you:
>
> http://www.iis.net/download/applicationwarmup
>
> Just feed it some URL's to hit when the app pool comes up and you're
> good to go. In the case of a non-HTTP activation WCF / WAS scenario
> you might consider having a "ping" page in the application you deploy
> under IIS that you configure the module to hit...just thinking out
> loud...
>
> Please let me know how it works out for you if you decide to make use
> of this approach (code for the event or the module) - would love to
> know myself! :)
>

tillig

unread,
Jun 8, 2010, 10:21:39 AM6/8/10
to Autofac
Here's a good article talking about different ways to initialize WCF
services:
http://blogs.msdn.com/b/wenlong/archive/2006/01/11/511514.aspx

As for a sample of AppInitialize, you can basically put this in your
App_Code folder:

public class Initializer
{
public static void AppInitialize()
{
// Put the initialization/app startup code here.
}
}

It doesn't matter what the class is called, just that it has the
static void method with that exact name. Also it has to be in a code
file in App_Code, not compiled into some other assembly. The article
talks a little more about that.

-T

On Jun 7, 11:09 am, felix <felix.wordwarr...@gmail.com> wrote:
> I think that the problem is the same described herehttp://blog.ploeh.dk/2010/05/18/SneakViewAtCastlesWCFFacility.aspx

tillig

unread,
Jun 8, 2010, 10:27:42 AM6/8/10
to Autofac
Oh, and Matt's idea about hooking into the IIS7.5 "warm startup"
system might also work, though I also haven't tried it. From the docs,
it appears that it requires you to modify applicationHost.config,
which is a system file (in C:\Windows\system32\inetsrv\config), so it
might throw a wrench in the works from a deployment perspective if you
go that route.

Here's some more info on applicationHost.config:
http://learn.iis.net/page.aspx/124/introduction-to-applicationhostconfig/

-T

felix

unread,
Jun 8, 2010, 2:12:56 PM6/8/10
to Autofac
this is interesting, but the Mark Seemann solution is for me more
elegant.
F.

Alex Meyer-Gleaves

unread,
Jun 9, 2010, 10:35:14 AM6/9/10
to aut...@googlegroups.com
Hi Felix,

You can certainly do the same thing that Mark shows in his post by creating your own AutofacServiceHostFactory and overriding the CreateServiceHost method.

In the current release version you would build the container and assign it to the Container property before calling down to the base implementation.
public class CustomAutofacHostFactory : AutofacServiceHostFactory
{
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
ContainerBuilder builder = new ContainerBuilder();
builder.Register(c => new Logger()).As<ILogger>();
builder.Register(c => new MyService(c.Resolve<ILogger>()));
Container = builder.Build();

return base.CreateServiceHost(constructorString, baseAddresses);
}
}

Once the changes that Travis (tillig) has made are released you would simply assign a value to the ContainerProvider instead.

public class CustomAutofacHostFactory : AutofacServiceHostFactory
{
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
ContainerBuilder builder = new ContainerBuilder();
builder.Register(c => new Logger()).As<ILogger>().WcfRequestScoped();
builder.Register(c => new MyService(c.Resolve<ILogger>()));
ContainerProvider = new ContainerProvider(builder.Build());

return base.CreateServiceHost(constructorString, baseAddresses);
}
}

All that is left then is to update the Factory attribute in your .svc file so that it points to your custom factory.
<%@ ServiceHost Language="C#" Debug="true" Service="MyWcfProject.MyService, MyWcfProject" CodeBehind="MyService.svc.cs" Factory="MyWcfProject.CustomAutofacHostFactory, MyWcfProject" %>

Cheers,

Alex.

felix

unread,
Jun 10, 2010, 8:50:17 AM6/10/10
to Autofac
great!!
thanks a lot!

On Jun 9, 4:35 pm, Alex Meyer-Gleaves <alex.meyerglea...@gmail.com>
wrote:
> > autofac+u...@googlegroups.com<autofac%2Bunsu...@googlegroups.com>
> > .
> > > > > >> > For more options, visit this group athttp://
> > groups.google.com/group/autofac?hl=en.
>
> > > > > > --
> > > > > > 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<autofac%2Bunsu...@googlegroups.com>
> > .
> > > > > > For more options, visit this group athttp://
> > groups.google.com/group/autofac?hl=en.
>
> > --
> > 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<autofac%2Bunsu...@googlegroups.com>
> > .
Reply all
Reply to author
Forward
0 new messages