Autofac Cannot resolve parameter serviceScopeFactory of constructor 'Void - c#

I get the following error when I try to inject IServiceScopeFactory in a class in my business layer: "Cannot resolve parameter 'Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory' of constructor 'Void"
I havent worked with AutoFac before so I am wondering what I am missing:
This is my code:
private static void ConfigureAutoFacIoC(ContainerBuilder builder, HttpConfiguration config, IAppBuilder app)
{
AutoFacRegister.RegisterDependency(builder, Assembly.GetExecutingAssembly());
RegisterWebApiDependency(builder);
builder.RegisterWebApiFilterProvider(config);
var container = builder.Build();
// Set the dependency resolver to be Autofac.
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
}
public static class AutoFacRegister
{
public static void RegisterDependency(ContainerBuilder builder, Assembly webApiAssembly)
{
RegisterDataLayer(builder);
RegisterBusinessLayer(builder);
RegisterShared(builder);
RegisterPresentationLayer(builder, webApiAssembly);
}
private static void RegisterDataLayer(ContainerBuilder builder)
{
builder.RegisterType<SBSContext>().InstancePerLifetimeScope();
builder.RegisterType<AgdaContext>().InstancePerLifetimeScope();
builder.RegisterType<MailingRepository>().As<IMailingRepository>();
builder.RegisterType<MembershipRepository>().As<IMembershipRepository>();
builder.RegisterType<CourseMomentRepository>().As<ICourseMomentRepository>();
builder.RegisterType<MedalRepository>().As<IMedalRepository>();
builder.RegisterType<PersonRepository>().As<IPersonRepository>();
builder.RegisterType<CourseRepository>().As<ICourseRepository>();
builder.RegisterType<OrganisationRepository>().As<IOrganisationRepository>();
builder.RegisterType<FunctionRepository>().As<IFunctionRepository>();
builder.RegisterType<PaymentRepository>().As<IPaymentRepository>();
builder.RegisterType<ChargeCategoryRepository>().As<IChargeCategoryRepository>();
builder.RegisterType<OutcodeRepository>().As<IOutcodeRepository>();
builder.RegisterType<UserRepository>().As<IUserRepository>();
builder.RegisterType<ViewPersonRepository>().As<IViewPersonRepository>();
builder.RegisterType<AgdaRepository>().As<IAgdaRepository>();
builder.RegisterType<ReportRepository>().As<IReportRepository>();
builder.RegisterType<ReportManager>().As<IReportManager>();
builder.RegisterType<CourseApplicationRepository>().As<ICourseApplicationRepository>();
builder.RegisterType<RepdayRepository>().As<IRepdayRepository>();
builder.RegisterType<ChargeCategoryRepository>().As<IChargeCategoryRepository>();
builder.RegisterType<CommuneRepository>().As<ICommuneRepository>();
builder.RegisterType<PapApiAmbassador>().As<IPapApiAmbassador>();
builder.RegisterType<VolenteerRepository>().As<IVolenteerRepository>();
builder.RegisterType<AgreementTypeRepository>().As<IAgreementTypeRepository>();
builder.RegisterType<CourseMomentStatusRepository>().As<ICourseMomentStatusRepository>();
builder.RegisterType<CourseTypeRepository>().As<ICourseTypeRepository>();
builder.RegisterType<AttestationRepository>().As<IAttestationRepository>();
builder.RegisterGeneric(typeof(GenericRepository<,>)).As(typeof(IGenericRepository<,>));
}
private static void RegisterBusinessLayer(ContainerBuilder builder)
{
var bllAssembly = AppDomain.CurrentDomain.GetAssemblies().
SingleOrDefault(assembly => assembly.GetName().Name == "SBS.Ferdinand.BusinessLayer");
builder.RegisterAssemblyTypes(typeof(IServiceScopeFactory).Assembly).As<IServiceScopeFactory>();
builder.RegisterAssemblyTypes(bllAssembly)
.Where(x => x.Name.EndsWith("Handler"))
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(bllAssembly)
.Where(x => x.Name.EndsWith("Helper"))
.AsImplementedInterfaces()
.SingleInstance();
builder.RegisterType<OrganisationMigrator>().As<IOrganisationMigrator>();
}
private static void RegisterShared(ContainerBuilder builder)
{
builder.RegisterType<BaseRequestModel>().AsImplementedInterfaces().InstancePerLifetimeScope();
builder.RegisterType<ImpersonateUser>().As<IImpersonateUser>();
builder.RegisterModule<NLogModule>();
builder.RegisterType<ApiApplicationSettings>().As<IApiApplicationSettings>().SingleInstance();
}
private static void RegisterPresentationLayer(ContainerBuilder builder, Assembly webApiAssembly)
{
builder.RegisterApiControllers(webApiAssembly);
}
public static void RegisterHangfireDependency(ContainerBuilder builder)
{
RegisterDataLayer(builder);
RegisterBusinessLayer(builder);
RegisterShared(builder);
builder.RegisterType<CronJobManager>().As<ICronJobManager>().InstancePerLifetimeScope();
}
}
public class NLogModule : Autofac.Module
{
private static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
e.Parameters = e.Parameters.Union(
new[]
{
new ResolvedParameter(
(p, i) => p.ParameterType == typeof (ILogger),
(p, i) => LogManager.GetLogger(p.Member.DeclaringType.FullName))
});
}
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
// Handle constructor parameters.
registration.Preparing += OnComponentPreparing;
}
}
where I try to inject the IServiceScopeFactory
public class PaymentHandler : IPaymentHandler
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public PaymentHandler(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}
}

It appears you're trying to kind of mix-and-match .NET 4.5 dependency injection (e.g., with the DependencyResolver mechanism in Web API) and new .NET Core dependency injection (e.g., IServiceProvider). The really short answer here is... you can't do that.
If you read the exception it tells you exactly what's missing:
Cannot resolve parameter 'Microsoft.Extensions.DependencyInjection.IServiceScopeFactory'
You have a constructor that takes an IServiceScopeFactory. You want Autofac to inject it. You didn't tell Autofac where to get it. No magic here: if you didn't register it with Autofac, Autofac's not going to be able to figure it out.
I'd guess what you want is the ability to create lifetime scopes inside that PaymentHandler. Since that's not really a thing in Web API with DependencyResolver, instead of trying to mix-and-match, you have to use Autofac directly.
Inject the ILifetimeScope instead.
public class PaymentHandler : IPaymentHandler
{
private readonly ILifetimeScope _scope;
public PaymentHandler(ILifetimeScope scope)
{
_scope = scope;
// now you can do
// using(var childScope = _scope.BeginLifetimeScope){ }
}
}
At this point, it'd be good to head over to the Autofac docs to learn more about lifetime scopes and how to work with them. But this should get you unblocked.

Related

How to register generic implementation for non-generic interface in Microsoft.DependencyInjection?

Title.
I have a non-generic logging abstraction and some implementations might be generic, e.g. Microsoft logging.
public interface ICustomLogger
{
void Log();
}
public class NLogLogger : ICustomLogger
{
private NLog.ILogger _logger;
void Log() => _logger.Log();
}
public class MicrosoftLogger<T> : ICustomLogger
{
private Microsoft.ILogger<T> _logger;
void Log() => _logger.Log();
}
How to setup MS.DI container so that it could resolve generic implementation where an interface is needed? Example of usage:
public class LoggerConsumer
{
private readonly ICustomLogger _logger;
public LoggerConsumer(ICustomLogger thereShouldBeMicrosoftGenericLogger)
{
_logger = thereShouldBeMicrosoftGenericLogger;
}
}
I'd like not to change my ICustomLogger to ICustomLogger<T> signature, because only Microsoft logging seems to be generic.
It is possible using Autofac.
If you use only the MS logging then you can create an Autofac module that will resolve the appropriate MS logger type for you.
using Autofac;
using Autofac.Core;
using Autofac.Core.Registration;
using Autofac.Core.Resolving.Pipeline;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
public class DependencyModule : Module
{
protected override void AttachToComponentRegistration(IComponentRegistryBuilder componentRegistry, IComponentRegistration registration)
{
registration.PipelineBuilding +=
(sender, e) =>
{
e.Use(
"ICustomLogger instance injection middleware",
PipelinePhase.ParameterSelection,
MiddlewareInsertionMode.StartOfPhase,
(context, next) =>
{
var parameters = context.Parameters.ToList();
parameters.Add(
new ResolvedParameter(
(parameter, context) => typeof(ICustomLogger) == parameter.ParameterType,
(parameter, context) =>
{
// This is the type the ctor of which contains the ICustomLogger parameter.
var type = parameter.Member.DeclaringType;
// This is the Microsoft.Extensions.Logging.ILogger<T> instance.
var msLogger = context.Resolve<ILoggerFactory>().CreateLogger(type);
// Here we create an instance of ICustomLogger.
return Activator.CreateInstance(typeof(MicrosoftLogger<>).MakeGenericType(type), msLogger)
}
)
);
context.ChangeParameters(parameters);
next.Invoke(context);
}
);
};
}
}
Then you need to register this module into Autofac container, e.g. when you create the hostbuilder for your app.
using Autofac;
using Autofac.Extensions.DependencyInjection;
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(
builder => builder.RegisterModule<DependencyModule>()
)
// rest is ommitted for clarity
;
Then your consumer class will get the correct instance of your MicrosoftLogger<T> type.

Dependency injection net core console application setup

I am trying to use dependency injection for a .Net Core Console application using the built in DI.
I have 2 following Methods :
private static void RegisterServices()
{
var collection = new ServiceCollection();
//repositories
collection.AddScoped<IAccountDataRepository, AccountDataRepository>();
collection.AddScoped<IClientDataRepository, ClientDataRepository>();
collection.AddScoped<IAddressDataRepository, AddressDataRepository>();
collection.AddScoped<IClientAccountDataRepository, ClientAccountDataRepository>();
//services
collection.AddScoped<IAccountDataService, AccountDataService>();
collection.AddScoped<IClientDataService, ClientDataService>();
collection.AddScoped<IAddressDataService, AddressDataService>();
collection.AddScoped<IClientAccountDataService, ClientAccountDataService>();
_serviceProvider = collection.BuildServiceProvider();
}
private static void DisposeServices()
{
if (_serviceProvider == null)
{
return;
}
if (_serviceProvider is IDisposable)
{
((IDisposable)_serviceProvider).Dispose();
}
}
I can get this to work in the main method by using this:
private static IServiceProvider _serviceProvider;
private static IClientDataRepository _clientDataRepository;
static void Main(string[] args)
{
RegisterServices();
_clientDataRepository = _serviceProvider.GetService<IClientDataRepository>();
However I need to inject the repository to the service and the service to main but I can t use the following in the service class :
_clientDataRepository = _serviceProvider.GetService<IClientDataRepository>();
Here is service:
public class ClientDataService : IClientDataService
{
private readonly ILogger _logger;
private readonly IClientDataRepository _clientDataRepository;
public ClientDataService(ILogger logger, IClientDataRepository clientDataRepository)
{
_logger = logger;
_clientDataRepository = clientDataRepository;
}
If I use
_clientDataRepository = _serviceProvider.GetService<IClientDataRepository>();
will give an error
Just resolve the service and the service provider will inject the repository into the service when building the object graph of the requested object
Based on the provided ClientDataService you would also need to make sure that all dependencies are registered with the service collection.
As it is current shown, ClientDataService also depends on ILogger which does not appear to be registered with the service collection.
services.AddLogging();
The following example uses the originally provided code and refactors to run the main using dependency injection.
public class Program
private readoonly IClientDataService service;
public Program(IClientDataService service) {
this.service = service;
}
public void SomeMethod() {
//...
}
//entry
public static void Main(string[] args) {
IServiceProvider serviceProvider = RegisterServices();
Program program = serviceProvider.GetService<Program>();
program.SomeMethod();
DisposeServices(serviceProvider);
}
//Support
private static IServiceProvider RegisterServices() {
var services = new ServiceCollection();
//repositories
services.AddScoped<IAccountDataRepository, AccountDataRepository>();
services.AddScoped<IClientDataRepository, ClientDataRepository>();
services.AddScoped<IAddressDataRepository, AddressDataRepository>();
services.AddScoped<IClientAccountDataRepository, ClientAccountDataRepository>();
//services
services.AddScoped<IAccountDataService, AccountDataService>();
services.AddScoped<IClientDataService, ClientDataService>();
services.AddScoped<IAddressDataService, AddressDataService>();
services.AddScoped<IClientAccountDataService, ClientAccountDataService>();
services.AddLogging(); //<-- LOGGING
//main
services.AddScoped<Program>(); //<-- NOTE THIS
return services.BuildServiceProvider();
}
private static void DisposeServices(IServiceProvider serviceProvider) {
if (serviceProvider == null) {
return;
}
if (serviceProvider is IDisposable sp) {
sp.Dispose();
}
}
}

Autofac - How to resolve a type registered in a module?

I have a problem using Autofac Module in my ASP.Net MVC Application.
I use a NLogModule to "register" Nlog :
public class NLogModule : Module
{
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += onComponentPreparing;
}
private static void onComponentPreparing(object sender, PreparingEventArgs e)
{
var t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(
new[]
{
new ResolvedParameter(
(p,i) => p.ParameterType == typeof(Portail.Utils.Logging.ILogger),
(p, i) => new NLogLogger(LogManager.GetLogger(t.FullName)))
});
}
}
I also add the module in my builder :
builder.RegisterModule<NLogModule>();
Everything works fine for the differents services registered in the builder which need my logger.
So now, I want to log every SQL Queries in a file. I follow the following article https://msdn.microsoft.com/en-us/library/dn469464(v=vs.113).aspx
Finally in my LoggerCommandInterceptor class, I need to resolve the ILogger. But it doesn't work.
Autofac.Core.Registration.ComponentNotRegisteredException: 'The requested service 'Portail.Utils.Logging.ILogger' has not been registered.
I don't understand why it doesn't work. The only difference with the services is that I create the instance of my LoggerCommandInterceptor myself
public PortailDbConfiguration()
{
SetDatabaseLogFormatter((context, writeAction) => new OneLineFormatter(context, writeAction));
this.AddInterceptor(new LoggerCommandInterceptor());
}
public class LoggerCommandInterceptor : IDbCommandInterceptor
{
#region Fields
private static ILogger _logger;
#endregion
#region Constructors
public LoggerCommandInterceptor()
{
var scope = EngineContext.Current.ContainerManager.Scope();
_logger = EngineContext.Current.ContainerManager.Resolve<ILogger>();
}
#endregion
...
and with the other services, Autofac create instances.
Can someone help me?
Thanks a lot.
Mike.

Self-Registering Libraries with Autofac 4 and vNext

i'd like to create a Plugin Enviroment for my ASP.Net 5.0 / MVC 6 Application. I'm using Autofac as IOC Container and i like to load the Plugins (Class Libraries) from the build in DNX LibraryManager. The goal of using the Library Manager is, that i don't have to care about NuGet Packages and Frameworks.
The Problem i have is the LifeCycle, i have to build the IOC Container before the instance of the LibraryManager is available. Because the Autofac Container provides his own IServiceProvider Instance which i have to inject within the ConfigureService() Method call (AddAutofac).
Does anyone know how to get this working?
Update: I have fixed my problem with Davids help and updated the code to get it working with the release candidates. Also i have added support for configuration.
In my DNX Class Library i implemented a Class for Self-Registration:
public class AutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c => new SimpleService())
.As<IService>()
.InstancePerLifetimeScope();
}
}
In my MVC WebApplication i have added the Class Library as Dependency.
Startup.cs
public IConfiguration Configuration { get; set; }
public class Startup
{
public Startup( IApplicationEnvironment applicationEnvironment )
{
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.SetBasePath( applicationEnvironment.ApplicationBasePath );
configurationBuilder.AddJsonFile( "appsettings.json" );
configurationBuilder.AddJsonFile( "autofac.json" );
configurationBuilder.AddEnvironmentVariables();
this.Configuration = configurationBuilder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDependencies();
}
public void Configure(IApplicationBuilder applicationBuilder, IHostingEnvironment hostingEnvironment)
{
applicationBuilder.UseDependencies( this.Configuration );
applicationBuilder.UseStaticFiles();
applicationBuilder.UseMvc();
}
}
I have created an DependencyResolver to keep the ContainerBuilder instance.
DependencyResolver.cs
public class DependencyResolver : IDependencyResolver
{
private IContainer container;
private readonly ContainerBuilder builder;
public DependencyResolver()
{
this.builder = new ContainerBuilder();
}
public void RegisterModule( IModule module )
{
this.builder.RegisterModule( module );
}
public void RegisterModules( IEnumerable<Assembly> assemblies )
{
this.builder.RegisterAssemblyModules(assemblies.ToArray());
}
public void Populate( IServiceCollection services)
{
this.builder.Populate( services );
}
public void Build()
{
this.container = this.builder.Build();
}
public T Resolve<T>() where T : class
{
return this.container?.Resolve<T>();
}
}
IDependencyResolver.cs
public interface IDependencyResolver
{
void RegisterModule( IModule module );
void RegisterModules( IEnumerable<Assembly> assemblies );
void Populate(IServiceCollection services);
void Build();
T Resolve<T>() where T : class;
}
Last but not least i have created an Extension Class
DependencyResolverExtensions.cs
public static class DependencyResolverExtensions
{
public static IServiceCollection AddDependencies( this IServiceCollection services )
{
DependencyResolver dependencyResolver = new DependencyResolver();
dependencyResolver.Populate(services);
ServiceDescriptor serviceDescriptor = new ServiceDescriptor(typeof ( IDependencyResolver ), dependencyResolver );
services.TryAdd(serviceDescriptor);
return services;
}
public static IApplicationBuilder UseDependencies(this IApplicationBuilder applicationBuilder, IConfiguration configuration)
{
IDependencyResolver dependencyResolver = applicationBuilder.GetService<IDependencyResolver>();
if (dependencyResolver == null) return applicationBuilder;
ILibraryManager libraryManager = applicationBuilder.GetService<ILibraryManager>();
if (libraryManager == null) return applicationBuilder;
IEnumerable<Assembly> assemblies = libraryManager.GetLoadableAssemblies();
dependencyResolver.RegisterModules(assemblies);
ConfigurationModule configurationModule = new ConfigurationModule( configuration );
dependencyResolver.RegisterModule( configurationModule );
dependencyResolver.Build();
IServiceProvider serviceProvider = dependencyResolver.Resolve<IServiceProvider>();
applicationBuilder.ApplicationServices = serviceProvider;
return applicationBuilder;
}
public static IEnumerable<Assembly> GetLoadableAssemblies(this ILibraryManager libraryManager)
{
List<Assembly> result = new List<Assembly>();
IEnumerable<Library> libraries = libraryManager.GetLibraries();
IEnumerable<AssemblyName> assemblyNames = libraries.SelectMany(e => e.Assemblies).Distinct();
assemblyNames = Enumerable.Where(assemblyNames, e => e.Name.StartsWith("MyLib."));
foreach (AssemblyName assemblyName in assemblyNames)
{
Assembly assembly = Assembly.Load(assemblyName);
result.Add(assembly);
}
return result;
}
public static T GetService<T>(this IApplicationBuilder applicationBuilder) where T : class
{
return applicationBuilder.ApplicationServices.GetService(typeof (T)) as T;
}
}
If you need to switch between different implementations, like mock and real data you can use the Autofac Configuration.
autofac.json
{
"components": [
{
"type": "MyLib.Data.EF.EntitiesData, MyLib.Data.EF",
"services": [
{
"type": "MyLib.Abstractions.IDataRepository, MyLib.Abstractions"
}
]
}
]
}
It's a shame that ConfigureServices is not injectable, that would make this a lot easier.
Looking at the code you should be safe to replace the IServiceProvider inside Configure(...) instead of inside ConfigureServices(...) and get the intended behavior. ApplicationServices is setable.
In your UseAutofac method you should be able to do something like:
public static IApplicationBuilder UseAutofac( [NotNull] this IApplicationBuilder applicationBuilder )
{
IAutofacResolver autofacResolver = applicationBuilder.GetService<IAutofacResolver>();
ILibraryManager libraryManager = applicationBuilder.GetService<ILibraryManager>();
autofacResolver.RegisterLibraryModules( libraryManager);
applicationBuilder.ApplicationServices = autofacResolver.Resolve();
return applicationBuilder;
}
I've come up with a solution that uses part of this, but also uses a ComponentContainer that addresses the potential memory leaks in the DependencyResolver. This also works with RC1. Not sure yet about RC2 as it's not complete enough for me to test.
The ComponentContainer looks like this:
public static class ComponentContainer {
static IContainer _container;
static ContainerBuilder _containerBuilder;
public static ContainerBuilder Builder {
get {
if (_containerBuilder == null)
_containerBuilder = new ContainerBuilder();
return _containerBuilder;
}
}
public static IServiceProvider ServiceProvider {
get {
if (_container == null)
_container = _containerBuilder.Build();
return _container.Resolve<IServiceProvider>();
}
}
public static ComponentFactory<TObject> Component<TObject>() => new ComponentFactory<TObject>(_container);
public static void RegisterAssembly(Assembly assembly) {
if (assembly == null) return;
foreach (var obj in assembly.GetTypes().Where(t => t.GetCustomAttribute<ExportAttribute>() != null)) {
ExportAttribute att = obj.GetCustomAttribute<ExportAttribute>();
if (att.ContractType != null) {
_containerBuilder.RegisterType(obj).As(att.ContractType);
} else {
foreach (var intf in obj.GetInterfaces())
_containerBuilder.RegisterType(obj).As(intf);
}
}
}
}
public class ComponentFactory<TObject> : IDisposable {
protected TObject CurrentObject;
protected ILifetimeScope CurrentScope;
public TObject Current => (TObject)CurrentObject;
public ComponentFactory(IContainer container) {
CurrentScope = container.BeginLifetimeScope();
CurrentObject = CurrentScope.Resolve<TObject>();
}
public TObject Component => CurrentObject;
public void Dispose() {
(CurrentObject as IDisposable)?.Dispose();
CurrentScope.Dispose();
}
}
Then in Startup.cs I do the following:
public virtual IServiceProvider ConfigureServices(IServiceCollection services) {
services.AddMvc();
services.AddOptions();
services.AddSession();
services.AddCaching();
var assemblyLoadContextAccessor = services.FirstOrDefault(s => s.ServiceType == typeof(IAssemblyLoadContextAccessor)).ImplementationInstance as IAssemblyLoadContextAccessor;
var libraryManager = services.FirstOrDefault(s => s.ServiceType == typeof(ILibraryManager)).ImplementationInstance as ILibraryManager;
var loadContext = assemblyLoadContextAccessor.Default;
foreach(var library in libraryManager.GetLibraries()) {
var assembly = loadContext.Load(library.Name);
if(assembly != null) {
var module = assembly.GetTypes().FirstOrDefault(t => t == typeof(IModule));
if(module != null)
ComponentContainer.Builder.RegisterAssemblyModules(assembly);
else
ComponentContainer.RegisterAssembly(assembly);
}
}
ComponentContainer.Builder.Populate(services);
return ComponentContainer.ServiceProvider;
}
To export modules within an assembly, I either mark them with an ExportAttribute or add a class to the assembly that implements Autofac's IModule. The code in ConfigureServices will enumerate through the application's modules and feed them to the static Builder in ComponentContainer. Once the container has been built, you can either resolve modules through injection in a constructor or you can request a specific type by:
(using var myComponentFactory = ComponentContainer.Component<IMyModule>()) {
//You can now access your component through myComponentFactory.Component
//Once it passes out of scope of using, it will be properly disposed of
//along with the scope from which it was created.
}
Edit: With the release of RC2, this code is no longer valid as the enumeration of assemblies and classes will fail. I haven't come up with a good solution yet. If anyone else has any suggestions for enumerating assemblies in RC2, please let me know.

How to resolve a named instance from a static class?

Does anyone have any idea about what i doing wrong?
I have a such static class:
public static class ApplicationContainer
{
private static ContainerBuilder builder = null;
private static IContainer container = null;
public static void Create()
{
builder = new ContainerBuilder();
builder.RegisterInstance(new Repository<Log>(RepositoryType.Main))
.As<IRepository<Log>>().SingleInstance()
.Named("Log", typeof(Repository<Log>));
container = builder.Build();
}
public static IContainer Container()
{
if (container != null) return container;
throw new Exception("Container is not ready.");
}
}
In Global.asax.cs of my MVC application i have:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ApplicationContainer.Create();
RegisterRoutes(RouteTable.Routes);
}
And now about problem: how can i to resolve named instance from a container?
public class DefaultLogger : ILogger
{
ApplicationContainer.Container().Resolve("Log", typeof(Repository<Log>);// <--- does not work
}
But when ApplicationContainer class is not static, resolving from container works very good.
I use autofac 2.2.4.
I believe you cannot compile this code since you are missing a closing ')' for your .Resolve(...) call.
That said, have you looked at the Autofac ASP.Net integration modules?

Categories