SIgnalR - An item with the same key has already been added - wcf

i am having an issue regarding a signalr (version 1.2.2. I cannot update toto 2+)/autofac/Nunit implementation. I am using an MVC client with a WCF service whixh pushes notifications to client. When I' m running the app using the web client and the service everything works as expected. When i try to test my service through NUnit everytime i try to create the hubcontext
GlobalHost.ConnectionManager.GetHubContext<ProductHub>()
i get
An item with the same key has already been added.
here is the full stack trace
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at Microsoft.AspNet.SignalR.Hubs.ReflectedHubDescriptorProvider.BuildHubsCache()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at System.Lazy`1.get_Value()
at Microsoft.AspNet.SignalR.Hubs.ReflectedHubDescriptorProvider.TryGetHub(String hubName, HubDescriptor& descriptor)
at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.c__DisplayClass1.b__0(IHubDescriptorProvider p)
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.GetHub(String hubName)
at Microsoft.AspNet.SignalR.Hubs.HubManagerExtensions.EnsureHub(IHubManager hubManager, String hubName, IPerformanceCounter[] counters)
at Microsoft.AspNet.SignalR.Infrastructure.ConnectionManager.GetHubContext(String hubName)
at Microsoft.AspNet.SignalR.Infrastructure.ConnectionManager.GetHubContext[T]()
Here is the autofac and signalr registration in global.asax service file
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
var builder = new ContainerBuilder();
builder.RegisterType<Product_WCF_Service>().AsSelf();
builder.RegisterType<DbFactory>().As<IDbFactory>();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
builder.RegisterAssemblyTypes(
new[] {
typeof(ProductService).Assembly
})
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(
new[] {
typeof(ProductRepository).Assembly
})
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
builder.RegisterType<ProductHub>().ExternallyOwned();
var container = builder.Build();
container.Resolve<IUnitOfWork>();
container.Resolve<IDbFactory>();
GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
AutofacHostFactory.Container = container;
AutoMapperConfiguration.Configure();
}
My service implementation
public class Product_WCF_Service : IProduct_WCF_Service
{
IUnitOfWork UnitOfWork;
IProductService ProductService;
public Product_WCF_Service(IUnitOfWork unitOfWork, IProductService productService)
{
this.ProductService = productService;
this.UnitOfWork = unitOfWork;
}
}
And my NUnit test which causes the exception to be thrown
[TestFixture]
public class WCF_Product_Service_Tests
{
private Mock<IProduct_WCF_Service> ProductWCFService;
private Mock<IUnitOfWork> UnitOfWork;
private Mock<IProductService> ProductService;
public WCF_Product_Service_Tests()
{
this.ProductWCFService = new Mock<IProduct_WCF_Service>();
this.UnitOfWork = new Mock<IUnitOfWork>();
this.ProductService = new Mock<IProductService>();
}
[Test]
public void RetreiveDataFromWCF_Service()
{
byte commitStatus = 1;
string response = string.Empty;
var service = new Product_WCF_Service(this.UnitOfWork.Object, this.ProductService.Object);
service.CreateProduct("", out response, out commitStatus);
}}
It's driving me crazy as i cannot test my service at all!

OK I searched around and finally i found a solution. I' leave it here just in case someone finds this useful
when registering autofac i enabled the property injection
var signalRConfig = new HubConfiguration();
var builder = new ContainerBuilder();
builder.RegisterType<ServiceHub>().ExternallyOwned(); // SignalR hub registration
builder.Register(i => signalRConfig.Resolver.Resolve<IConnectionManager>().GetHubContext<ServiceHub>()).ExternallyOwned();
builder.RegisterType<Product_WCF_Service>().AsSelf();
builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(
new[] {
typeof(ProductService).Assembly
})
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(
new[] {
typeof(ProductRepository).Assembly
})
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
builder.RegisterType<Product_WCF_Service>()
.PropertiesAutowired();
var container = builder.Build();
signalRConfig.Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
signalRConfig.EnableCrossDomain = true;
RouteTable.Routes.MapHubs(signalRConfig);
AutofacHostFactory.Container = container;
AutoMapperConfiguration.Configure();
In my service i added the hubcontext as a property in
public class Product_WCF_Service : IProduct_WCF_Service{
IUnitOfWork UnitOfWork;
IProductService ProductService;
public IHubContext InstanceHubContext { get; set; }
public Product_WCF_Service(IUnitOfWork unitOfWork, IProductService productService)
{
this.ProductService = productService;
this.UnitOfWork = unitOfWork;
}
and it worked as expected! I can now access the hubcontext as usual
this.InstanceHubContext.Clients.All.onNotSavedProduct(message);
Of course you will also need the Autofac.Integration.SignalR and Autofac.Integration.Wcf packages

Related

Why is my custom `AuthentictionStateProvider` not null in AddSingleton but null in AddScoped

I had previously asked a question that was answered properly, but the problem is that when my custom AuthenticationStateProvider is registered as a scoped
services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
I get the following error:
System.InvalidOperationException: GetAuthenticationStateAsync was called before SetAuthenticationState
But, when it is registered as a singleton, it works correctly, However, the single instance creates for the lifetime of the application domain by AddSingelton, and so this is not good.(Why? Because of :))
What should I do to register my custom AuthenticationStateProvider as a scoped, but its value is not null?
Edit:
According to #MrC aka Shaun Curtis Comment:
It's my CustomAuthenticationStateProvider:
public class CustomAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider
{
private readonly IServiceScopeFactory _scopeFactory;
public CustomAuthenticationStateProvider(ILoggerFactory loggerFactory, IServiceScopeFactory scopeFactory)
: base(loggerFactory) =>
_scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
protected override TimeSpan RevalidationInterval { get; } = TimeSpan.FromMinutes(30);
protected override async Task<bool> ValidateAuthenticationStateAsync(
AuthenticationState authenticationState, CancellationToken cancellationToken)
{
// Get the user from a new scope to ensure it fetches fresh data
var scope = _scopeFactory.CreateScope();
try
{
var userManager = scope.ServiceProvider.GetRequiredService<IUsersService>();
return await ValidateUserAsync(userManager, authenticationState?.User);
}
finally
{
if (scope is IAsyncDisposable asyncDisposable)
{
await asyncDisposable.DisposeAsync();
}
else
{
scope.Dispose();
}
}
}
private async Task<bool> ValidateUserAsync(IUsersService userManager, ClaimsPrincipal? principal)
{
if (principal is null)
{
return false;
}
var userIdString = principal.FindFirst(ClaimTypes.UserData)?.Value;
if (!int.TryParse(userIdString, out var userId))
{
return false;
}
var user = await userManager.FindUserAsync(userId);
return user is not null;
}
}
And it's a program configuration and service registration:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
#region Authentication
//Authentication
services.AddDbContextFactory<ApplicationDbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("LocalDBConnection"),
serverDbContextOptionsBuilder =>
{
var minutes = (int)TimeSpan.FromMinutes(3).TotalSeconds;
serverDbContextOptionsBuilder.CommandTimeout(minutes);
serverDbContextOptionsBuilder.EnableRetryOnFailure();
})
.AddInterceptors(new CorrectCommandInterceptor()); ;
});
//add policy
services.AddAuthorization(options =>
{
options.AddPolicy(CustomRoles.Admin, policy => policy.RequireRole(CustomRoles.Admin));
options.AddPolicy(CustomRoles.User, policy => policy.RequireRole(CustomRoles.User));
});
// Needed for cookie auth.
services
.AddAuthentication(options =>
{
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.SlidingExpiration = false;
options.LoginPath = "/";
options.LogoutPath = "/login";
//options.AccessDeniedPath = new PathString("/Home/Forbidden/");
options.Cookie.Name = ".my.app1.cookie";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = SameSiteMode.Lax;
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = context =>
{
var cookieValidatorService = context.HttpContext.RequestServices.GetRequiredService<ICookieValidatorService>();
return cookieValidatorService.ValidateAsync(context);
}
};
});
#endregion
//AutoMapper
services.AddAutoMapper(typeof(MappingProfile).Assembly);
//CustomAuthenticationStateProvider
services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
.
.
}
Don't worry about the AddSingelton in the Blazor apps. Scoped dependencies act the same as Singleton registered dependencies in Blazor apps (^).
Blazor WebAssembly apps don't currently have a concept of DI scopes. Scoped-registered services behave like Singleton services.
The Blazor Server hosting model supports the Scoped lifetime across HTTP requests (Just for the Razor Pages or MVC portion of the app) but not across SignalR connection/circuit messages among components that are loaded on the client.
That's why there's a scope.ServiceProvider.GetRequiredService here to ensure the retrived user is fetched from a new scope and has a fresh data.
Actually this solution is taken from the Microsoft's sample.
Your problem is probably here:
var scope = _scopeFactory.CreateScope();
/...
var userManager = scope.ServiceProvider.GetRequiredService<IUsersService>();
You create a new IOC container and request the instance of IUsersService from that container.
If IUsersService is Scoped, it creates a new instance.
IUsersService requires various other services which the new container must provide.
public UsersService(IUnitOfWork uow, ISecurityService securityService, ApplicationDbContext dbContext, IMapper mapper)
Here's the definition of those services in Startup:
services.AddScoped<IUnitOfWork, ApplicationDbContext>();
services.AddScoped<IUsersService, UsersService>();
services.AddScoped<IRolesService, RolesService>();
services.AddScoped<ISecurityService, SecurityService>();
services.AddScoped<ICookieValidatorService, CookieValidatorService>();
services.AddScoped<IDbInitializerService, DbInitializerService>();
IUnitOfWork and ISecurityService are both Scoped, so it creates new instances of these in the the new Container. You almost certainly don't want that: you want to use the ones from the Hub SPA session container.
You have a bit of a tangled web so without a full view of everything I can't be sure how to restructure things to make it work.
One thing you can try is to just get a standalone instance of IUsersService from the IOC container using ActivatorUtilities. This instance gets instantiated with all the Scoped services from the main container. Make sure you Dispose it if it implements IDisposable.
public class CustomAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider
{
private readonly IServiceProvider _serviceProvider;
public CustomAuthenticationStateProvider(ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
: base(loggerFactory) =>
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(scopeFactory));
protected override TimeSpan RevalidationInterval { get; } = TimeSpan.FromMinutes(30);
protected override async Task<bool> ValidateAuthenticationStateAsync(
AuthenticationState authenticationState, CancellationToken cancellationToken)
{
// Get an instance of IUsersService from the IOC Container Service to ensure it fetches fresh data
IUsersService userManager = null;
try
{
userManager = ActivatorUtilities.CreateInstance<IUsersService>(_serviceProvider);
return await ValidateUserAsync(userManager, authenticationState?.User);
}
finally
{
userManager?.Dispose();
}
}
private async Task<bool> ValidateUserAsync(IUsersService userManager, ClaimsPrincipal? principal)
{
if (principal is null)
{
return false;
}
var userIdString = principal.FindFirst(ClaimTypes.UserData)?.Value;
if (!int.TryParse(userIdString, out var userId))
{
return false;
}
var user = await userManager.FindUserAsync(userId);
return user is not null;
}
}
For reference this is my test code using the standard ServerAuthenticationStateProvider in a Blazor Server Windows Auth project.
public class MyAuthenticationProvider : ServerAuthenticationStateProvider
{
IServiceProvider _serviceProvider;
public MyAuthenticationProvider(IServiceProvider serviceProvider, MyService myService)
{
_serviceProvider = serviceProvider;
}
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
MyService? service = null;
try
{
service = ActivatorUtilities.CreateInstance<MyService>(_serviceProvider);
// Do something with service
}
finally
{
service?.Dispose();
}
return base.GetAuthenticationStateAsync();
}
}

Custom IServiceProviderFactory in ASP.NET Core

I wrote a custom IServiceProviderFactory and installed it in Program.cs of a new app like this:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new PropertyInjectingContainerFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
It does lead to the correct configure function in Startup.cs getting called:
public void ConfigureContainer(PropertyInjectingContainerFactory.Builder builder)
{
builder.AddInjectAttribute<InjectDependencyAttribute>();
}
However, my created container only ever resolves two services: IConfiguration and IHost.
Everything else is resolved by the default container apparantly (for instance a service like ILogger<T> on a controller). What do I do wrong?
Here's the code for my custom factory - and please understand that I probably should be using an existing third-party container, but I also want to understand how this all fits together.
public class PropertyInjectingContainerFactory : IServiceProviderFactory<PropertyInjectingContainerFactory.Builder>
{
public Builder CreateBuilder(IServiceCollection services)
{
return new Builder(services);
}
public IServiceProvider CreateServiceProvider(Builder containerBuilder)
{
return containerBuilder.CreateServiceProvider();
}
public class Builder
{
internal readonly IServiceCollection services;
internal List<Type> attributeTypes = new List<Type>();
public Builder(IServiceCollection services)
{
this.services = services;
}
public Builder AddInjectAttribute<A>()
where A : Attribute
{
attributeTypes.Add(typeof(A));
return this;
}
public IServiceProvider CreateServiceProvider()
=> new PropertyInjectingServiceProvider(services.BuildServiceProvider(), attributeTypes.ToArray());
}
class PropertyInjectingServiceProvider : IServiceProvider
{
private readonly IServiceProvider services;
private readonly Type[] injectAttributes;
public PropertyInjectingServiceProvider(IServiceProvider services, Type[] injectAttributes)
{
this.services = services;
this.injectAttributes = injectAttributes;
}
// This function is only called for `IConfiguration` and `IHost` - why?
public object GetService(Type serviceType)
{
var service = services.GetService(serviceType);
InjectProperties(service);
return service;
}
private void InjectProperties(Object target)
{
var type = target.GetType();
var candidateProperties = type.GetProperties(System.Reflection.BindingFlags.Public);
var props = from p in candidateProperties
where injectAttributes.Any(a => p.GetCustomAttributes(a, true).Any())
select p;
foreach (var prop in props)
{
prop.SetValue(target, services.GetService(prop.PropertyType));
}
}
}
}

Access violation when trying to get the database context in a hosted service

I'm trying to do a periodic job on my clients using a hosted service. This is my hosted service:
namespace Commander.Services
{
public class UpdateClientsStateService : IHostedService, IDisposable
{
private readonly ILogger<UpdateClientsStateService> logger;
private readonly IServiceScopeFactory scopeFactory;
private Timer timer;
public UpdateClientsStateService(ILogger<UpdateClientsStateService> logger, IServiceScopeFactory scopeFactory)
{
this.logger = logger;
this.scopeFactory = scopeFactory;
}
public void Dispose()
{
timer?.Dispose();
}
public Task StartAsync(CancellationToken cancellationToken)
{
timer = new Timer(o =>
{
using var scope = scopeFactory.CreateScope();
var clientRepository = scope.ServiceProvider.GetRequiredService<CommanderDbContext>();
var clients = clientRepository.Clients;
foreach (var client in clients)
{
logger.LogInformation($"{client.Id}");
}
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}
Whenever I try to get the CommanderDbContext service, iisexpress says:
The program '[16808] iisexpress.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
This is my ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CommanderDbContext>(opt => opt.UseMySql(Configuration.GetConnectionString("MySql")));
services.AddControllers().AddNewtonsoftJson();
services.AddScoped<IRequestRepository, SqlServerRequestRepository>();
services.AddScoped<IClientRepository, SqlServerClientRepository>();
services.AddHttpContextAccessor();
services.AddHostedService<UpdateClientsStateService>();
services.AddSingleton(o =>
{
var accessor = o.GetRequiredService<IHttpContextAccessor>();
var request = accessor.HttpContext.Request;
var uri = string.Concat(request.Scheme, "://", request.Host.ToUriComponent());
return new PaginationUriService(uri);
});
}

Asp.Net Core 2.0 Xunit Tests

I am new .asp.net core. I am testing a controller that renders a view to a string and then utilises evo pdf to render the view.
All is working perfectly and I am also able to successfully test using postman.
However my test app errors when I use vs 2017 test explorer to debug my test (Xunit).
Searched Locations within the razor engine
The error occurs within my RenderViewToString method as my razor view engine is unable to locate the view to render. The paths searched to locate the views are as expected. Any guidance is appreciated.
//Unit Test Code
[Fact]
public async void GetPdf()
{
var response = await _client.PostAsJsonAsync<Common.DTO.Invoice>("/api/values/1", GetDummyData());
using (var file = System.IO.File.Create(#"c:\\Test" + DateTime.Now.ToString("yyyyyMMddHHmmss") + ".pdf"))
{
//create a new file to write to
await response.Content.CopyToAsync(file);
await file.FlushAsync(); // flush back to disk before disposing
}
}
//Render view to string service
public interface IViewRenderService
{
Task<string> RenderToStringAsync(string viewName, ViewDataDictionary viewData);
}
public class ViewRenderService : IViewRenderService
{
private readonly IRazorViewEngine _razorViewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly IServiceProvider _serviceProvider;
public ViewRenderService(IRazorViewEngine razorViewEngine,ITempDataProvider tempDataProvider,IServiceProvider serviceProvider)
{
_razorViewEngine = razorViewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
public async Task<string> RenderToStringAsync(string viewName, ViewDataDictionary viewData)
{
var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
using (var sw = new StringWriter())
{
var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);
if (viewResult.View == null)
{
throw new ArgumentNullException($"{viewName} does not match any available view");
}
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewData,
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
sw,
new HtmlHelperOptions()
);
await viewResult.View.RenderAsync(viewContext);
return sw.ToString();
}
}
}
I was getting the same error with core 2.0. The problem is RazorViewEngine is not working as expected with empty RouteData object;
So i injected IHttpContextAccessor and got HttpContext and RouteData from it;
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IViewRenderService, ViewRenderService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc();
}
RazorToStringHelper.cs:
public interface IViewRenderService
{
Task<string> RenderToStringAsync(string viewName, object model);
}
public class ViewRenderService : IViewRenderService
{
private readonly IRazorViewEngine _razorViewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly IHttpContextAccessor _httpContextAccessor;
public ViewRenderService(
IRazorViewEngine razorViewEngine,
IHttpContextAccessor httpContextAccessor,
ITempDataProvider tempDataProvider)
{
_razorViewEngine = razorViewEngine;
_tempDataProvider = tempDataProvider;
_httpContextAccessor = httpContextAccessor;
}
public async Task<string> RenderToStringAsync(string viewName, object model)
{
var httpContext = _httpContextAccessor.HttpContext;
var actionContext = new ActionContext(httpContext, httpContext.GetRouteData(), new ActionDescriptor());
var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);
if (viewResult.View == null)
{
throw new ArgumentNullException($"{viewName} does not match any available view");
}
using (var sw = new StringWriter())
{
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
};
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
sw,
new HtmlHelperOptions()
);
await viewResult.View.RenderAsync(viewContext);
return sw.ToString();
}
}
}
Due to time constraints I abandoned the XUnit approach, wrote a test app and also
utilised postman as this was an api requirement to render a pdf from a razor view.

The AutofacServiceHost.Container static property must be set before services can be instantiated

Within my XXXX.WS WCF services project I'm trying to get DI/IOC using autofac going...been at it all day but I think I'm close (different errors are progress here)...this error I can't understand how to shake..."AutofacServieHost.Container static property must be set..."..but I think I am setting it!?! What am I doing wrong?
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register(c => new DatabaseFactory()).As<IDatabaseFactory>().Named<DatabaseFactory>("DBFactory");
builder.Register(c => new ListingSqlRepository(c.ResolveNamed<DatabaseFactory>("DBFactory"))).As<IListingSqlRepository>().Named<ListingSqlRepository>("LSR");
builder.Register(c => new ListingRepository(c.ResolveNamed<ListingSqlRepository>("LSR"))).As<IListingRepository>().Named<ListingRepository>("LR");
builder.Register(c => new Service1(c.ResolveNamed<IListingRepository>("LR"))).As<IService1>();
using (var container = builder.Build())
{
Uri address = new Uri("http://localhost:57924/Service1");
ServiceHost host = new ServiceHost(typeof(Service1), address);
host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), string.Empty);
host.AddDependencyInjectionBehavior<IService1>(container);
//BREAKS HERE?
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true, HttpGetUrl = address });
host.Open();
Console.WriteLine("The host has been opened.");
Console.ReadLine();
host.Close();
Environment.Exit(0);
}
}
Then the SERVICE:
namespace LOTW2012.WS
{
public class Service1 : IService1
{
private IListingRepository _listingRepository { get; set; }
public Service1(IListingRepository iLR) {
this._listingRepository = iLR;
}
public Service1()
{
}
public List<Listing> GetListingsByStateName(string stateName)
{
//todo ..getall for now
var listings = _listingRepository.GetAll().ToList();
return listings;
}
You need to tell the Autofac WCF integration about the container you build by setting the property in question:
var builder = new ContainerBuilder();
// ...
AutofacHostFactory.Container = builder.Build();
// ...
This will allow Autofac to resolve service types.