How to create a UnityNancyBootstrapper-implementation that will work with a OWIN Startup class - unity-container

I'm trying to create a Nancy/Unity-bootstrapper that can work with a OWIN-startup-class like the one described here:
Minimal sample: Self hosted Nancy using Owin, Unity bootstrapper including xUnit test
public class Startup
{
public void Configuration(IAppBuilder app)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IMessageHelper, MessageHelper>();
app.UseNancy(new NancyOptions
{
EnableClientCertificates = true,
Bootstrapper = new NancyOwinBoxBootstrapper(container)
});
}
}
public class NancyOwinBoxBootstrapper : UnityNancyBootstrapper
{
private IUnityContainer _container;
public NancyOwinBoxBootstrapper(IUnityContainer container)
{
_container = container;
}
protected override IUnityContainer GetApplicationContainer()
{
return _container;
}
}
The sample contained in the NancyOwinBox.zip works fine, but it is based on Nancy.Bootstrappers.Unity version 1.1. When i upgrade the NuGet package to the latest version (1.2) the sample fails with:
Resolution of the dependency failed, type = "Nancy.Bootstrapper.IApplicationStartup", name = "Nancy.ViewEngines.ViewEngineApplicationStartup".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, System.Collections.Generic.IEnumerable`1[Nancy.ViewEngines.IViewEngine], is an interface and cannot be constructed. Are you missing a type mapping?
At the time of the exception, the container was:
Resolving Nancy.ViewEngines.ViewEngineApplicationStartup,Nancy.ViewEngines.ViewEngineApplicationStartup (mapped from Nancy.Bootstrapper.IApplicationStartup, Nancy.ViewEngines.ViewEngineApplicationStartup)
Resolving parameter "viewEngines" of constructor Nancy.ViewEngines.ViewEngineApplicationStartup(System.Collections.Generic.IEnumerable1[[Nancy.ViewEngines.IViewEngine, Nancy, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null]] viewEngines, Nancy.ViewEngines.IViewCache viewCache, Nancy.ViewEngines.IViewLocator viewLocator)
Resolving System.Collections.Generic.IEnumerable1[Nancy.ViewEngines.IViewEngine],(none)
The current type, System.Collections.Generic.IEnumerable`1[Nancy.ViewEngines.IViewEngine], is an interface and cannot be constructed. Are you missing a type mapping?
Does anyone have an idea why this error occurs?

You need to register the EnumerableExtension in your container, like so:
container.AddNewExtension<EnumerableExtension>();
See UnityNancyBootstrapper.cs for Reference.

Related

Autoregistration with Unity and Prism not working

I'm having this configuration with Unity and Prism:
public class EmployeeDataService : IEmployeeDataService
{
}
public class EmployeeController(IEmployeeDataService dataService)
{
this.dataService = dataService;
}
public class EmployeeModuleInit : IModule
{
readonly IUnityContainer container;
readonly IRegionManager regionManager;
readonly EmployeeController employeeController;
public EmployeeModuleInit(IUnityContainer container, IRegionManager regionManager, EmployeeController employeeController)
{
this.container = container;
this.regionManager = regionManager;
this.employeeController = employeeController;
}
}
The types are mapped using:
Container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.TypeName,
WithLifetime.Transient );
Yet, at start-up I'm getting this error:
{"The current type, IEmployeeDataService, is an interface and cannot be constructed. Are you missing a type mapping?"}
IUnityContainer and IRegionManager are properly registered and resolved, however they are registered manually in the Prism.UnityExtensions.UnityBootstrapper.cs and I don't want to manually register all types in the project.
Any ideas how to solve this?
Thank you,
Daniel
That registration by convention is registering all types with a name. I think you probably wanted this instead...
Container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Transient);

Quartz.net and Ninject: how to bind implementation to my job using NInject

I am actually working in an ASP.Net MVC 4 web application where we are using NInject for dependency injection. We are also using UnitOfWork and Repositories based on Entity framework.
We would like to use Quartz.net in our application to start some custom job periodically. I would like that NInject bind automatically the services that we need in our job.
It could be something like this:
public class DispatchingJob : IJob
{
private readonly IDispatchingManagementService _dispatchingManagementService;
public DispatchingJob(IDispatchingManagementService dispatchingManagementService )
{
_dispatchingManagementService = dispatchingManagementService ;
}
public void Execute(IJobExecutionContext context)
{
LogManager.Instance.Info(string.Format("Dispatching job started at: {0}", DateTime.Now));
_dispatchingManagementService.DispatchAtomicChecks();
LogManager.Instance.Info(string.Format("Dispatching job ended at: {0}", DateTime.Now));
}
}
So far, in our NInjectWebCommon binding is configured like this (using request scope):
kernel.Bind<IDispatchingManagementService>().To<DispatchingManagementService>();
Is it possible to inject the correct implementation into our custom job using NInject ? and how to do it ? I have read already few posts on stack overflow, however i need some advises and some example using NInject.
Use a JobFactory in your Quartz schedule, and resolve your job instance there.
So, in your NInject config set up the job (I'm guessing at the correct NInject syntax here)
// Assuming you only have one IJob
kernel.Bind<IJob>().To<DispatchingJob>();
Then, create a JobFactory: [edit: this is a modified version of #BatteryBackupUnit's answer here]
public class NInjectJobFactory : IJobFactory
{
private readonly IResolutionRoot resolutionRoot;
public NinjectJobFactory(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
// If you have multiple jobs, specify the name as
// bundle.JobDetail.JobType.Name, or pass the type, whatever
// NInject wants..
return (IJob)this.resolutionRoot.Get<IJob>();
}
public void ReturnJob(IJob job)
{
this.resolutionRoot.Release(job);
}
}
Then, when you create the scheduler, assign the JobFactory to it:
private IScheduler GetSchedule(IResolutionRoot root)
{
var schedule = new StdSchedulerFactory().GetScheduler();
schedule.JobFactory = new NInjectJobFactory(root);
return schedule;
}
Quartz will then use the JobFactory to create the job, and NInject will resolve the dependencies for you.
Regarding scoping of the IUnitOfWork, as per a comment of the answer i linked, you can do
// default for web requests
Bind<IUnitOfWork>().To<UnitOfWork>()
.InRequestScope();
// fall back to `InCallScope()` when there's no web request.
Bind<IUnitOfWork>().To<UnitOfWork>()
.When(x => HttpContext.Current == null)
.InCallScope();
There's only one caveat that you should be aware of:
With incorrect usage of async in a web request, you may mistakenly be resolving a IUnitOfWork in a worker thread where HttpContext.Current is null. Now without the fallback binding, this would fail with an exception which would show you that you've done something wrong. With the fallback binding however, the issue may present itself in an obscured way. That is, it may work sometimes, but sometimes not. This is because there will be two (or even more) IUnitOfWork instances for the same request.
To remedy this, we can make the binding more specific. For this, we need some parameter to tell us to use another than InRequestScope(). Have a look at:
public class NonRequestScopedParameter : Ninject.Parameters.IParameter
{
public bool Equals(IParameter other)
{
if (other == null)
{
return false;
}
return other is NonRequestScopedParameter;
}
public object GetValue(IContext context, ITarget target)
{
throw new NotSupportedException("this parameter does not provide a value");
}
public string Name
{
get { return typeof(NonRequestScopedParameter).Name; }
}
// this is very important
public bool ShouldInherit
{
get { return true; }
}
}
now adapt the job factory as follows:
public class NInjectJobFactory : IJobFactory
{
private readonly IResolutionRoot resolutionRoot;
public NinjectJobFactory(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return (IJob) this.resolutionRoot.Get(
bundle.JobDetail.JobType,
new NonrequestScopedParameter()); // parameter goes here
}
public void ReturnJob(IJob job)
{
this.resolutionRoot.Release(job);
}
}
and adapt the IUnitOfWork bindings:
Bind<IUnitOfWork>().To<UnitOfWork>()
.InRequestScope();
Bind<IUnitOfWork>().To<UnitOfWork>()
.When(x => x.Parameters.OfType<NonRequestScopedParameter>().Any())
.InCallScope();
This way, if you use async wrong, there'll still be an exception, but IUnitOfWork scoping will still work for quartz tasks.
For any users that could be interested, here is the solution that finally worked for me.
I have made it working doing some adjustment to match my project. Please note that in the method NewJob, I have replaced the call to Kernel.Get by _resolutionRoot.Get.
As you can find here:
public class JobFactory : IJobFactory
{
private readonly IResolutionRoot _resolutionRoot;
public JobFactory(IResolutionRoot resolutionRoot)
{
this._resolutionRoot = resolutionRoot;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
try
{
return (IJob)_resolutionRoot.Get(
bundle.JobDetail.JobType, new NonRequestScopedParameter()); // parameter goes here
}
catch (Exception ex)
{
LogManager.Instance.Info(string.Format("Exception raised in JobFactory"));
}
}
public void ReturnJob(IJob job)
{
}
}
And here is the call schedule my job:
public static void RegisterScheduler(IKernel kernel)
{
try
{
var scheduler = new StdSchedulerFactory().GetScheduler();
scheduler.JobFactory = new JobFactory(kernel);
....
}
}
Thank you very much for your help
Thanks so much for your response. I have implemented something like that and the binding is working :):
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var resolver = DependencyResolver.Current;
var myJob = (IJob)resolver.GetService(typeof(IJob));
return myJob;
}
As I told before I am using in my project a service and unit of work (based on EF) that are both injected with NInject.
public class DispatchingManagementService : IDispatchingManagementService
{
private readonly IUnitOfWork _unitOfWork;
public DispatchingManagementService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
}
Please find here how I am binding the implementations:
kernel.Bind<IUnitOfWork>().To<EfUnitOfWork>()
kernel.Bind<IDispatchingManagementService>().To<DispatchingManagementService>();
kernel.Bind<IJob>().To<DispatchingJob>();
To resume, the binding of IUnitOfWork is done for:
- Eevery time a new request is coming to my application ASP.Net MVC: Request scope
- Every time I am running the job: InCallScope
What are the best practices according to the behavior of EF ? I have find information to use CallInScope. Is it possible to tell NInject to get a scope ByRequest everytime a new request is coming to the application, and a InCallScope everytime my job is running ? How to do that ?
Thank you very much for your help

How do I use AutoFac with SignalR 2.0.0 where hubs are in an external dll?

We have a need to be able to drop new projects/dlls into our main project and have the main project pick them up and be able to use them. It was decided to use AutoFac to handle this need. This way the main project would not need a direct reference to any of the other projects/dlls we want to use. Here is the global.asax:
var builder = new ContainerBuilder();
var directoryName = HttpContext.Current.Server.MapPath("~/bin/");
var cfg = new ModularityLoader(new ModularityConfig(Path.Combine(directoryName, #"Modules")), new Log4NetLogger(typeof(ModularityConfig)));
cfg.RegisterModulesFromCatalog(builder);
builder.RegisterType<AssembliesResolver>().AsImplementedInterfaces();
builder.RegisterType<AppsSecurityFeatureResolver>().AsImplementedInterfaces();
builder.RegisterType<FeaturesAutofacAuthoriztationFilter>()
.AsWebApiAuthorizationFilterFor<ApiController>().InstancePerApiRequest();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
builder.RegisterControllers(typeof(MvcApplication).Assembly);
Container = builder.Build();
We have post-build events on all projects that copy their dlls into the bin directory of our main project. All of the dlls are loaded in here with var cfg = new ModularityLoader.
See image:
builder.Build() calls the following class in any of the dlls in our project that implements Autofac.Module such as this one:
public class AutofacModuleConfig : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterApiControllers(typeof(AutofacModuleConfig).Assembly);
}
}
Here is where the trouble with SignalR comes in. I would like to put RouteTable.Routes.MapHubs() into AutofacModuleConfig, but SignalR 2.0.0+ no longer supports this. Instead, it wants you to create a Startup class like this:
[assembly: OwinStartup("SignalRConfig", typeof(KL.Apps.TestHarness.SignalR.Startup))]
namespace KL.Apps.TestHarness.SignalR
{
public static class Startup
{
public static void Configuration(IAppBuilder app)
{
app.MapSignalR("/signalr", new HubConfiguration());
}
}
}
Note: To get this to work I added the following to the web.config:
<add key="owin:appStartup" value="SignalRConfig" />
SignalR also requires Hub classes like this:
[HubName("BatchHub")]
public class BatchHub : Hub
{
public void RemoveBatchRow(Guid batchId)
{
Clients.All.RemoveBatchRow(batchId);
}
}
Having the Startup class and Hub classes in my main project works perfectly. However, because of the unique nature of AutoFac, none of my Hubs from my external dlls are getting loaded up. I was thinking to try to find a way to force AutofacModuleConfig.Load to accept RouteTable.Routes.MapHubs(), but adding this line breaks the code.
I was thinking to go back to an earlier version of SignalR so I can use RouteTable.Routes.MapHubs() but I would really like to use the most up to date version.
Any ideas?
Thanks in advance.
EDIT 1:
I found this: https://code.google.com/p/autofac/wiki/SignalRIntegration
It seems to be the answer the the problem. However, RegisterHubs does not exist off of the builder object even after installing the Autofac.SignalR NuGet package...
var builder = new ContainerBuilder();
builder.RegisterHubs(Assembly.GetExecutingAssembly());
EDIT 2:
So this is what my AutofacModuleConfig looks like now, but my hubs are still not showing up in javascript.
namespace OurName.IOC
{
public class AutofacModuleConfig : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
AutofacSignalRConfig.Load(builder);
builder.RegisterApiControllers(typeof(AutofacModuleConfig).Assembly);
}
}
}
namespace Autofac.Integration.SignalR
{
public static class AutofacSignalRConfig
{
public static void Load(ContainerBuilder builder)
{
builder.RegisterHubs(Assembly.GetExecutingAssembly());
}
}
}
Still not working though. In javascript I cannot see my hubs.
$(document).ready(function(){
var myHub = $.connection.BatchHub;
});
myHub is null.
EDIT 3:
Tried this last night. I removed AutofacSignalRConfig and this is how the main Global.asax looks now:
var builder = new ContainerBuilder();
var directoryName = HttpContext.Current.Server.MapPath("~/bin/");
var cfg = new ModularityLoader(new ModularityConfig(Path.Combine(directoryName, #"Modules")), new Log4NetLogger(typeof(ModularityConfig)));
cfg.RegisterModulesFromCatalog(builder);
builder.RegisterType<AssembliesResolver>().AsImplementedInterfaces();
builder.RegisterType<AppsSecurityFeatureResolver>().AsImplementedInterfaces();
builder.RegisterType<FeaturesAutofacAuthoriztationFilter>()
.AsWebApiAuthorizationFilterFor<ApiController>().InstancePerApiRequest();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
builder.RegisterControllers(typeof(MvcApplication).Assembly);
foreach (var assembly in cfg.LoadedAssemblies)
{
var hubs = builder.RegisterHubs(assembly);
}
Container = builder.Build();
GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(Container);
Notice how I tried to take the output of cfg (which is a collection of all assemblies found in the bin folder) and then foreach through them in order to execute builder.RegisterHubs on each one. Still not picking up my hubs from any of those assemblies though.
Does there need to be a Startup class in each of my imported dlls too? If so, how would I go about calling it?
EDIT 4:
Tried this too with no success:
foreach (var assembly in cfg.LoadedAssemblies)
{
//var hubs = builder.RegisterHubs(assembly);
var a = assembly.GetExportedTypes().Where(x => x.BaseType == typeof (Hub));
foreach (var x in a)
{
builder.RegisterType(x);
}
}
See image for debug info:
EDIT 5:
Jim Bolla thank you for the input. Here is my first try at your suggestion.
public class AssemblyLocator : IAssemblyLocator
{
public IList<Assembly> GetAssemblies()
{
var directoryName = HttpContext.Current.Server.MapPath("~/bin/");
var cfg = new ModularityLoader(new ModularityConfig(Path.Combine(directoryName, #"Modules")), new Log4NetLogger(typeof(ModularityConfig)));
return cfg.LoadedAssemblies;
}
}
Also added this just above Container = builder.Build:
builder.RegisterType<AssemblyLocator>().As<IAssemblyLocator>().SingleInstance();
AssemblyLocator.GetAssemblies() is now getting called.
... Testing ...
EDIT 6:
Okay. So now when I throw a breakpoint into javascript, I can see $.connection.BatchHub which is great! However, when trying to call the hub method RemoveBatchRow on the server-side I get the following error:
"Using a Hub instance not created by the HubPipeline is unsupported."
Here is the stack trace:
at
Microsoft.AspNet.SignalR.Hubs.NullClientProxy.TryInvokeMember(InvokeMemberBinder
binder, Object[] args, Object& result) at CallSite.Target(Closure ,
CallSite , Object , Guid ) at
System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite
site, T0 arg0, T1 arg1) at
KL.Apps.WebIndex.Hubs.BatchHub.RemoveBatchRow(Guid batchId) in
d:\Source\Apps Framework
Modules\WebIndex\Main\Source\KL.Apps.WebIndex\Hubs\BatchHub.cs:line 20
at
KL.Apps.WebIndex.API.Batch.BatchLockController.TryLockBatchAsync(String
batchId) in d:\Source\Apps Framework
Modules\WebIndex\Main\Source\KL.Apps.WebIndex\API\Batch\BatchLockController.cs:line
30 at lambda_method(Closure , Object , Object[] ) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.b__c(Object
instance, Object[] methodParameters) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object
instance, Object[] arguments) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1
func, CancellationToken cancellationToken)
I am calling the hub method from one of my remote dlls like this:
new BatchHub().RemoveBatchRow(gId);
You can see the definition for BatchHub above.
Any other ideas?

Injecting IDbConnectionFactory into Service class

I have started using ServiceStack today. So, let me know if I am doing something completely wrong.
I am trying to inject Db into my Service class, for which I am using this code
[TestFixture]
public class UserServiceTests
{
private UserService service;
[SetUp]
public void SetUp()
{
var appHost = new BasicAppHost();
var dbFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider);
appHost.Container.Register<IDbConnectionFactory>(dbFactory);
service = new UserService();
service.SetAppHost(appHost);
}
[Test]
public void Calling_post_method_with_valid_User_saves_it_in_database()
{
var User = new User { Name = "Acme Limited" };
var id = service.Post(User);
Assert.AreEqual(1, id);
}
}
There are two problems:
1) I am getting exception:
Could not load file or assembly 'System.Data.SQLite, Version=1.0.82.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Is there an easy way to fix this? And do we really need SQLite for testing, is there is Fake object available?
2) The compiler is warning about - service.SetAppHost(appHost). SetAppHost is depricated.
How can I inject Db into my service class without using SetAppHost?
Any ideas?
Sounds like you have a platform incompatibility issue with Sqlite, make sure you're using the right Sqlite package for your machine.
As for service.SetAppHost(appHost) the deprecated message says to use service.SetResolver(appHost) as IAppHost also implements IResolver, so use that.

Using Autofac for DI into WCF service hosted in ASP.NET application

I'm having trouble injecting services dependencies into my WCF service using Autofac 1.4.5. I've read and followed the Autofac wiki page on WcfIntegration but my debugging shows me that my WCF service is created by the System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance() method and not by the AutofacWebServiceHostFactory. What am I doing wrong?
I've set up my ajax.svc file to look like the one in the example for use with WebHttpBinding:
<%# ServiceHost Language="C#" Debug="true"
Service="Generic.Frontend.Web.Ajax, Generic.Frontend.Web"
Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory,
Autofac.Integration.Wcf" %>
My WCF service class Ajax is defined like this:
namespace Generic.Frontend.Web
{
[ServiceContract]
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Ajax
{
public MapWebService MapWebService { get; set;}
public Ajax() {
// this constructor is being called
}
public Ajax(MapWebService mapWebService)
{
// this constructor should be called
MapWebService = mapWebService;
}
[WebGet(ResponseFormat = WebMessageFormat.Json)]
[OperationContract(Name = "mapchange")]
public MapChangeResult ProcessMapChange(string args)
{
// use the injected service here
var result = MapWebService.ProcessMapChange(args);
return result;
}
}
}
Now I've used the wiring up in the Global.asax.cs as shown in the wiki mentioned above:
var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacModuleWebservice());
var container = builder.Build();
AutofacServiceHostFactory.Container = container;
with
class AutofacModuleWebservice : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<Ajax>();
builder.Register<MapWebService>().ContainerScoped();
}
}
In my web.config I have
<services>
<service name="Generic.Frontend.Web.Ajax">
<endpoint address="http://mysite.com/ajax.svc/" binding="webHttpBinding"
contract="Generic.Frontend.Web.Ajax" />
</service>
</services>
.
The service already works fine but I can't get the Autofac bits (read: creation/injection) to work. Any ideas?
Edit:
Removing the default constructor unfortunately leads to the following exception:
System.InvalidOperationException:
The service type provided could not be loaded as a service because it does not
have a default (parameter-less) constructor. To fix the problem, add a default
constructor to the type, or pass an instance of the type to the host.
Cheers, Oliver
Is your service setup with InstanceContextMode.Single? If it is then wcf will create your service using the default constructor. To get around this change your instance context mode and let autofac manage the lifetime of your service.
Try deleting the default Ajax constructor and modifying your constructor to this. If it gets run with mapWebService == null that would indicate a resolution problem.
public Ajax(MapWebService mapWebService = null)
{
// this constructor should be called
MapWebService = mapWebService;
}
I just got the same System.InvalidOperationException and solved it by changing the ServiceBehavior InstanceContextMode of the implementation from InstanceContextMode.PerCall to InstanceContextMode.PerSession, perhaps your AutoFac lifetime scope is out of sync with your web service implementation?
For testing AutoFac service creation I recommend creating a unit test and directly resolving them as this will highlight any issues and give more meaningful exception messages. For services with a request lifetime scope create a test aspx page and again resolve them directly.
I had the same problem and came across this question while searching for an answer.
In my case, using property injection worked, and the code in the question already has a property that can be used:
namespace Generic.Frontend.Web
{
[ServiceContract]
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Ajax
{
// inject the dependency here
public MapWebService MapWebService { get; set;}
[WebGet(ResponseFormat = WebMessageFormat.Json)]
[OperationContract(Name = "mapchange")]
public MapChangeResult ProcessMapChange(string args)
{
// use the injected service here
var result = MapWebService.ProcessMapChange(args);
return result;
}
}
}
and register to use property injection (sample code from the wiki and syntax has changed as this is now using version 2.5.2.830):
builder.RegisterType<Ajax>().PropertiesAutowired();
Following the instructions solved it for me:
code.google.com/p/autofac/wiki/… I simply do : builder.RegisterType();
and I've followed their instuructions for changing the .svc file.
When you look at your .svc file you do not get any hints about something being wrong there btw?
You host it throu the iis and do not utilize WAS, I do not see your code for overriding global.asax.cs
Add the global file to your solution and there you implement:
protected void Application_Start(object sender, EventArgs e)
{
// build and set container in application start
IContainer container = AutofacContainerBuilder.BuildContainer();
AutofacHostFactory.Container = container;
}
AutofacContainerBuilder is my container builder.

Resources