Last active
May 6, 2020 10:49
-
-
Save chgeuer/47267184d8689e9ead93db01dea41cbb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace PlayingWithIoCWebApp | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reactive.Disposables; | |
using System.Reactive.Linq; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Hosting; | |
using Microsoft.Extensions.Logging; | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
CreateHostBuilder(args).Build().Run(); | |
} | |
public static IHostBuilder CreateHostBuilder(string[] args) => | |
Host.CreateDefaultBuilder(args) | |
.ConfigureWebHostDefaults(webBuilder => | |
{ | |
webBuilder.UseStartup<Startup>(); | |
}); | |
} | |
public class Startup | |
{ | |
public Startup(IConfiguration configuration) { Configuration = configuration; } | |
public IConfiguration Configuration { get; } | |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |
{ | |
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } | |
app.UseRouting(); | |
app.UseAuthorization(); | |
app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); | |
} | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddControllers(); | |
// inject an Observable | |
services.AddSingleton<IObservable<WeatherForecast>>(_ => SomeDataSource.WeatherData); | |
// inject a transient dependency (which will require SomeSpecificSingletonDependency) | |
services.AddTransient<ISomeValueProvider, SomeEphemeralThing>(); | |
// inject a functional dependency | |
services.AddSingleton<Func<Task<Secret>>>(_ => ExternalThing.GetSecret); | |
// inject a transient dependency | |
services.AddSingleton(_ => new SomeSpecificSingletonDependency(someValue: Guid.NewGuid().ToString())); | |
// inject a transient (main) dependency | |
services.AddTransient<IWeatherForecastService, WeatherForecastService>(); | |
} | |
} | |
public class Secret | |
{ | |
public string SecretValue { get; set; } | |
} | |
public static class ExternalThing | |
{ | |
public static async Task<Secret> GetSecret() | |
{ | |
await Console.Out.WriteLineAsync("Somebody wants a secret"); | |
await Task.Delay(TimeSpan.FromSeconds(1)); | |
return new Secret { SecretValue = "some secret" }; | |
} | |
} | |
public interface ISomeValueProvider | |
{ | |
string SomeValue { get; } | |
} | |
public class SomeEphemeralThing : ISomeValueProvider | |
{ | |
public string SomeValue { get; } | |
public SomeEphemeralThing(SomeSpecificSingletonDependency otherDependency) | |
{ | |
var myOwnIdentity = Guid.NewGuid(); | |
this.SomeValue = $"{otherDependency.SomeValue} -- {myOwnIdentity}"; | |
} | |
} | |
public class SomeSpecificSingletonDependency | |
{ | |
public string SomeValue { get; } | |
public SomeSpecificSingletonDependency(string someValue) { this.SomeValue = someValue; } | |
} | |
public static class SomeDataSource | |
{ | |
private static readonly string[] Summaries = new[] | |
{ | |
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" | |
}; | |
public static IObservable<WeatherForecast> WeatherData | |
{ | |
get | |
{ | |
var rng = new Random(); | |
return Observable.Create<WeatherForecast>(observer => | |
{ | |
foreach (var index in Enumerable.Range(1, 5)) | |
{ | |
var item = new WeatherForecast | |
{ | |
Date = DateTime.Now.AddDays(index), | |
TemperatureC = rng.Next(-20, 55), | |
Summary = Summaries[rng.Next(Summaries.Length)] | |
}; | |
observer.OnNext(item); | |
} | |
observer.OnCompleted(); | |
return Disposable.Empty; | |
}); | |
} | |
} | |
} | |
public class WeatherForecast | |
{ | |
public DateTime Date { get; set; } | |
public int TemperatureC { get; set; } | |
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); | |
public string Summary { get; set; } | |
} | |
public interface IWeatherForecastService | |
{ | |
Task<ResponseType> CreateForecast(); | |
} | |
public class WeatherForecastService : IWeatherForecastService | |
{ | |
private readonly ILogger<WeatherForecastController> _logger; | |
private readonly IObservable<WeatherForecast> getWeatherForecastData; | |
private readonly SomeSpecificSingletonDependency someSingleton; | |
private readonly ISomeValueProvider ephemeralThingie; | |
private readonly Func<Task<Secret>> getSecret; | |
public WeatherForecastService( | |
ILogger<WeatherForecastController> logger, | |
IObservable<WeatherForecast> getWeatherForecastData, | |
Func<Task<Secret>> getSecret, | |
SomeSpecificSingletonDependency someSingleton, | |
ISomeValueProvider ephemeralThingie) | |
{ | |
_logger = logger; | |
this.getWeatherForecastData = getWeatherForecastData; | |
this.someSingleton = someSingleton; | |
this.ephemeralThingie = ephemeralThingie; | |
this.getSecret = getSecret; | |
} | |
async Task<ResponseType> IWeatherForecastService.CreateForecast() | |
{ | |
var secret = await this.getSecret(); | |
var weather = getWeatherForecastData.ToEnumerable(); | |
return new ResponseType | |
{ | |
Secret = secret.SecretValue, | |
Weather = weather, | |
SingletonValue = this.someSingleton.SomeValue, | |
EphemeralValue = this.ephemeralThingie.SomeValue, | |
}; | |
} | |
} | |
[ApiController] | |
[Route("[controller]")] | |
public class WeatherForecastController : ControllerBase | |
{ | |
private readonly IWeatherForecastService weatherService; | |
public WeatherForecastController(IWeatherForecastService weatherService) { this.weatherService = weatherService; } | |
[HttpGet] | |
public Task<ResponseType> Get() => weatherService.CreateForecast(); | |
} | |
public class ResponseType | |
{ | |
public string Secret { get; set; } | |
public string EphemeralValue { get; set; } | |
public string SingletonValue { get; set; } | |
public IEnumerable<WeatherForecast> Weather { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment