Unverified Commit bb1510c3 authored by Steve Smith's avatar Steve Smith Committed by GitHub

Updated Startup to use IHost not IWebHost (#106)

* Updated Startup to use IHost not IWebHost
Configured Autofac using Module

* Added registration of any handler implementing IHandle<T>

* Fixed tests with in memory database vs. sqlite
parent f0ff77b4
using Autofac;
using Autofac.Extensions.DependencyInjection;
using CleanArchitecture.Core;
using CleanArchitecture.SharedKernel.Interfaces;
using CleanArchitecture.Infrastructure.Data;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Reflection;
namespace CleanArchitecture.Infrastructure
{
public static class ContainerSetup
{
public static IServiceProvider InitializeWeb(Assembly webAssembly, IServiceCollection services) =>
new AutofacServiceProvider(BaseAutofacInitialization(setupAction =>
{
setupAction.Populate(services);
setupAction.RegisterAssemblyTypes(webAssembly).AsImplementedInterfaces();
}));
public static IContainer BaseAutofacInitialization(Action<ContainerBuilder> setupAction = null)
{
var builder = new ContainerBuilder();
var coreAssembly = Assembly.GetAssembly(typeof(DatabasePopulator));
var infrastructureAssembly = Assembly.GetAssembly(typeof(EfRepository));
var sharedKernelAssembly = Assembly.GetAssembly(typeof(IRepository));
builder.RegisterAssemblyTypes(sharedKernelAssembly, coreAssembly, infrastructureAssembly).AsImplementedInterfaces();
setupAction?.Invoke(builder);
return builder.Build();
}
}
}
using Autofac;
using CleanArchitecture.Core;
using CleanArchitecture.Infrastructure.Data;
using CleanArchitecture.Infrastructure.DomainEvents;
using CleanArchitecture.SharedKernel.Interfaces;
using System.Collections.Generic;
using System.Reflection;
using Module = Autofac.Module;
namespace CleanArchitecture.Infrastructure
{
public class DefaultInfrastructureModule : Module
{
private bool _isDevelopment = false;
private List<Assembly> _assemblies = new List<Assembly>();
public DefaultInfrastructureModule(bool isDevelopment, Assembly callingAssembly = null)
{
_isDevelopment = isDevelopment;
var coreAssembly = Assembly.GetAssembly(typeof(DatabasePopulator));
var infrastructureAssembly = Assembly.GetAssembly(typeof(EfRepository));
_assemblies.Add(coreAssembly);
_assemblies.Add(infrastructureAssembly);
if (callingAssembly != null)
{
_assemblies.Add(callingAssembly);
}
}
protected override void Load(ContainerBuilder builder)
{
if (_isDevelopment)
{
RegisterDevelopmentOnlyDependencies(builder);
}
else
{
RegisterProductionOnlyDependencies(builder);
}
RegisterCommonDependencies(builder);
}
private void RegisterCommonDependencies(ContainerBuilder builder)
{
builder.RegisterType<DomainEventDispatcher>().As<IDomainEventDispatcher>()
.InstancePerLifetimeScope();
builder.RegisterType<EfRepository>().As<IRepository>()
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(_assemblies.ToArray())
.AsClosedTypesOf(typeof(IHandle<>));
}
private void RegisterDevelopmentOnlyDependencies(ContainerBuilder builder)
{
// TODO: Add development only services
}
private void RegisterProductionOnlyDependencies(ContainerBuilder builder)
{
// TODO: Add production only services
}
}
}
using CleanArchitecture.Infrastructure.Data;
using Autofac.Extensions.DependencyInjection;
using CleanArchitecture.Infrastructure.Data;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
......@@ -12,7 +14,7 @@ namespace CleanArchitecture.Web
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
......@@ -35,8 +37,20 @@ namespace CleanArchitecture.Web
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
// logging.AddAzureWebAppDiagnostics(); add this if deploying to Azure
});
});
}
}
using Ardalis.ListStartupServices;
using Autofac;
using CleanArchitecture.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
......@@ -6,19 +7,23 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace CleanArchitecture.Web
{
public class Startup
{
public Startup(IConfiguration config) => this.Configuration = config;
private readonly IWebHostEnvironment _env;
public Startup(IConfiguration config, IWebHostEnvironment env)
{
Configuration = config;
_env = env;
}
public IConfiguration Configuration { get; }
public IServiceProvider ConfigureServices(IServiceCollection services)
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
......@@ -42,10 +47,16 @@ namespace CleanArchitecture.Web
config.Path = "/listservices";
});
return ContainerSetup.InitializeWeb(Assembly.GetExecutingAssembly(), services);
//return ContainerSetup.InitializeWeb(Assembly.GetExecutingAssembly(), services);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new DefaultInfrastructureModule(_env.EnvironmentName == "Development"));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.EnvironmentName == "Development")
{
......
......@@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using Microsoft.AspNetCore.TestHost;
using System.Linq;
namespace CleanArchitecture.FunctionalTests
{
......@@ -20,19 +21,35 @@ namespace CleanArchitecture.FunctionalTests
.UseSolutionRelativeContentRoot("src/CleanArchitecture.Web")
.ConfigureServices(services =>
{
// Create a new service provider.
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
// Remove the app's ApplicationDbContext registration.
var descriptor = services.SingleOrDefault(
d => d.ServiceType ==
typeof(DbContextOptions<AppDbContext>));
// Add a database context (AppDbContext) using an in-memory
// database for testing.
if (descriptor != null)
{
services.Remove(descriptor);
}
// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<AppDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(serviceProvider);
});
//// Create a new service provider.
//var serviceProvider = new ServiceCollection()
// .AddEntityFrameworkInMemoryDatabase()
// .BuildServiceProvider();
//// Add a database context (AppDbContext) using an in-memory
//// database for testing.
//services.AddDbContext<AppDbContext>(options =>
//{
// options.UseInMemoryDatabase("InMemoryDbForTesting");
// options.UseInternalServiceProvider(serviceProvider);
//});
services.AddScoped<IDomainEventDispatcher, NoOpDomainEventDispatcher>();
// Build the service provider.
......
using CleanArchitecture.Core.Entities;
using Autofac;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.Core.Events;
using CleanArchitecture.Infrastructure;
using CleanArchitecture.Infrastructure.DomainEvents;
......@@ -11,7 +12,9 @@ namespace CleanArchitecture.UnitTests.Core.DomainEvents
[Fact]
public void NotReturnAnEmptyListOfAvailableHandlers()
{
var container = ContainerSetup.BaseAutofacInitialization();
var builder = new ContainerBuilder();
builder.RegisterModule(new DefaultInfrastructureModule(isDevelopment: true));
var container = builder.Build();
var domainEventDispatcher = new DomainEventDispatcher(container);
var toDoItemCompletedEvent = new ToDoItemCompletedEvent(new ToDoItem());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment