مهارتهای تزریق وابستگیها در برنامههای NET Core. - قسمت دوم - الگوی Service Locator
نویسنده: وحید نصیری
تاریخ: ۱۳۹۷/۱۰/۰۹ ۱۳:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
namespace System
{
public interface IServiceProvider
{
object GetService(Type serviceType);
}
} using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace CoreIocServices
{
public interface IProductService
{
void Delete(int id);
}
public class ProductService : IProductService
{
private readonly ITestService _testService;
private readonly ILogger<ProductService> _logger;
public ProductService(IServiceProvider serviceProvider)
{
_testService = serviceProvider.GetRequiredService<ITestService>();
_logger = serviceProvider.GetService<ILogger<ProductService>>() ?? NullLogger<ProductService>.Instance;
}
public void Delete(int id)
{
_testService.Run();
_logger.LogInformation($"Deleted a product with id = {id}");
}
}
} namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceProviderServiceExtensions
{
public static T GetRequiredService<T>(this IServiceProvider provider);
public static T GetService<T>(this IServiceProvider provider);
}
} using System;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
namespace Utils
{
public static class ServiceLocatorProvider
{
private static readonly Lazy<IServiceProvider> _serviceProviderBuilder =
new Lazy<IServiceProvider>(GetServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication);
/// <summary>
/// A lazy loaded thread-safe singleton
/// </summary>
public static IServiceProvider Current { get; } = _serviceProviderBuilder.Value;
private static IServiceProvider GetServiceProvider()
{
var services = new ServiceCollection();
ConfigureServices(services);
return services.BuildServiceProvider();
}
private static void ConfigureServices(IServiceCollection services)
{
// TODO: add other services here ... services.AddSingleton ....
}
}
public static class ServiceLocator
{
public static object GetService(Type serviceType)
{
return ServiceLocatorProvider.Current.GetService(serviceType);
}
public static TService GetService<TService>()
{
return ServiceLocatorProvider.Current.GetService<TService>();
}
public static object GetRequiredService(Type serviceType)
{
return ServiceLocatorProvider.Current.GetRequiredService(serviceType);
}
public static TService GetRequiredService<TService>()
{
return ServiceLocatorProvider.Current.GetService<TService>();
}
public static void RunScopedService<T, S>(Action<S, T> callback)
{
using (var serviceScope = ServiceLocatorProvider.Current.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<S>();
callback(context, serviceScope.ServiceProvider.GetRequiredService<T>());
if (context is IDisposable disposable)
{
disposable.Dispose();
}
}
}
public static void RunScopedService<S>(Action<S> callback)
{
using (var serviceScope = ServiceLocatorProvider.Current.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<S>();
callback(context);
if (context is IDisposable disposable)
{
disposable.Dispose();
}
}
}
public static T RunScopedService<T, S>(Func<S, T> callback)
{
using (var serviceScope = ServiceLocatorProvider.Current.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<S>();
return callback(context);
}
}
}
}