I realize this question is asked a lot. But I cannot figure out the solution to this problem.
The thing i am trying to resolve is create three seperate interfaces (Singleton Scoped, InstancePerRequest). And register all the services under their implemented interface, without having to manually add them to DI container.
Autofac Scanning Assemblies for certain class type
Autofac register assembly types
Autofac assembly scanning - .NET Core
Before you say duplicate hear me out.
I have provided a solution to the question asked. But i would like to search the whole solution and not be restricted to a project. I have addded my autofac module inside the Services project so it registers what exists inside services projects. Please see answer below for a better understanding.
I have tried to implement a multi project scanning see code below. It does not work.
Here is my Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Here is my Configure container in my Startup Class. I have left out all others since this is just a new ASP.NET Core Project.
public void ConfigureContainer(ContainerBuilder builder)
{
//builder.RegisterType<EpisodeServices>().As<IEpisodeService>().InstancePerLifetimeScope(); This works
var executingDirectory = AppDomain.CurrentDomain.BaseDirectory;
//The sth is my Solution's header for example Sth.Core, Sth.Models, Sth.Services all are childs to the Sth Solution
string[] files = Directory.GetFiles(executingDirectory, "Sth.*.dll", SearchOption.AllDirectories);
var listOfAssemblies = new List<Assembly>();
foreach (var file in files)
listOfAssemblies.Add(Assembly.LoadFile(file));
builder
.RegisterAssemblyTypes(listOfAssemblies.ToArray())
.Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(ISthScopedService))))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
So far so good.
Here is an example Service so you can fully see my implementation.
public class EpisodeServices : IEpisodeService
{
public IList<Episode> GetEpisodes()
{
return new List<Episode>
{
new Episode { Id = 1, Name = "Some Name", Description = "Some Description" }
};
}
}
And here is the interface:
public interface IEpisodeService : ISthScopedService
{
IList<Episode> GetEpisodes();
}
Here is the injection to the controller
public class EpisodeController : Controller
{
private readonly IEpisodeService _episodeService;
public EpisodeController(IEpisodeService episodeService)
{
_episodeService = episodeService;
}
public IActionResult Index()
{
var data = _episodeService.GetEpisodes();
return Content(data[0].Name);
}
}
If i run this like this i get an Invalid Operation Exception: Unable to resolve service for type namespace.IEpisodeService while attempting to activate EpisodeController.
Could someone provide more implementation details on how to achieve this?