IOC+EF+Core项目搭建IOC注入及框架(二)
配置ServiceCollection
/// <summary>
/// 表示IServiceCollection的扩展
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 向应用程序添加服务并配置服务提供者
/// </summary>
/// <param name="services">Collection of service descriptors</param>
/// <param name="configuration">Configuration of the application</param>
/// <returns>Configured service provider</returns>
public static IServiceProvider ConfigureApplicationServices(this IServiceCollection services, IConfiguration configuration)
{
//添加TestConfig配置参数
services.ConfigureStartupConfig<TestConfig>(configuration.GetSection("Test"));
services.AddHttpContextAccessor(); //创建、初始化和配置引擎
var engine = EngineContext.Create();
engine.Initialize(services);
IServiceProvider serviceProvider = engine.ConfigureServices(services, configuration); return serviceProvider;
} /// <summary>
/// 创建、绑定和注册指定的配置参数作为服务
/// </summary>
public static TConfig ConfigureStartupConfig<TConfig>(this IServiceCollection services, IConfiguration configuration) where TConfig : class, new()
{
if (services == null)
throw new ArgumentNullException(nameof(services)); if (configuration == null)
throw new ArgumentNullException(nameof(configuration)); //create instance of config
var config = new TConfig(); //bind it to the appropriate section of configuration
configuration.Bind(config); //and register it as a service
services.AddSingleton(config); return config;
} /// <summary>
/// 注册Http上下文存取器
/// </summary>
/// <param name="services">Collection of service descriptors</param>
/// 服务描述符的集合
public static void AddHttpContextAccessor(this IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
}
模型引擎
/// <summary>
///实现这个接口的类可以作为组成Nop引擎的各种服务的门户。
///Fdit功能、模块和实现通过这个接口访问大多数Nop功能。
/// </summary>
public interface IEngine
{
/// <summary>
/// Initialize 引擎
/// </summary>
/// <param name="services">Collection of service descriptors</param>
void Initialize(IServiceCollection services); /// <summary>
/// Add and configure services
/// </summary>
/// <param name="services">服务描述符的集合</param>
/// <param name="configuration">Configuration of the application</param>
/// <returns>Service provider</returns>
IServiceProvider ConfigureServices(IServiceCollection services, IConfiguration configuration); /// <summary>
/// Configure HTTP request 管道
/// </summary>
/// <param name="application">Builder for configuring an application's request pipeline</param>
void ConfigureRequestPipeline(IApplicationBuilder application); /// <summary>
/// Resolve 集合
/// </summary>
/// <typeparam name="T">Type of resolved service</typeparam>
/// <returns>Resolved service</returns>
T Resolve<T>() where T : class; /// <summary>
/// Resolve dependency
/// </summary>
/// <param name="type">Type of resolved service</param>
/// <returns>Resolved service</returns>
object Resolve(Type type); /// <summary>
/// Resolve dependencies
/// </summary>
/// <typeparam name="T">Type of resolved services</typeparam>
/// <returns>Collection of resolved services</returns>
IEnumerable<T> ResolveAll<T>(); /// <summary>
/// Resolve unregistered service
/// </summary>
/// <param name="type">Type of service</param>
/// <returns>Resolved service</returns>
object ResolveUnregistered(Type type);
}
单例模式
/// <summary>
/// 单例模式
/// </summary>
/// <typeparam name="T"></typeparam>
public class Singleton<T> : BaseSingleton
{
private static T instance; /// <summary>
/// The singleton instance for the specified type T. Only one instance (at the time) of this object for each type of T.
/// </summary>
public static T Instance
{
get => instance;
set
{
instance = value;
AllSingletons[typeof(T)] = value;
}
}
} /// <summary>
/// 提供对存储的所有“单例”的访问 <see cref="Singleton{T}"/>.
/// </summary>
public class BaseSingleton
{
static BaseSingleton()
{
AllSingletons = new Dictionary<Type, object>();
} /// <summary>
/// 到单例实例的类型字典。
/// </summary>
public static IDictionary<Type, object> AllSingletons { get; }
}
/// <summary>
/// 提供对引擎的单件实例的访问。
/// </summary>
public class EngineContext
{
#region 方法
/// <summary>
/// Create a static instance of the Nop engine.
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
public static IEngine Create()
{
//create NopEngine as engine
return Singleton<IEngine>.Instance ?? (Singleton<IEngine>.Instance = new NopEngine());
} /// <summary>
/// 将静态引擎实例设置为提供的引擎。使用这个方法来提供您自己的引擎实现。
/// </summary>
public static void Replace(IEngine engine)
{
Singleton<IEngine>.Instance = engine;
} #endregion #region 属性 /// <summary>
/// 获取单例Nop引擎,用于访问Nop服务。
/// </summary>
public static IEngine Current
{
get
{
if (Singleton<IEngine>.Instance == null)
{
Create();
} return Singleton<IEngine>.Instance;
}
}
#endregion
}
/// <summary>
/// 代表 Nop engine
/// </summary>
public class NopEngine : IEngine
{
#region 属性
/// <summary>
/// 服务
/// </summary>
private IServiceProvider _serviceProvider { get; set; }
/// <summary>
/// 服务
/// </summary>
public virtual IServiceProvider ServiceProvider => _serviceProvider;
#endregion #region Utilities /// <summary>
/// Get IServiceProvider
/// </summary>
/// <returns>IServiceProvider</returns>
protected IServiceProvider GetServiceProvider()
{
var accessor = ServiceProvider.GetService<IHttpContextAccessor>();
var context = accessor.HttpContext;
//var a=context == null ? null : RequestServices ?? ServiceProvider; context==null?null:SericeProvider return context?.RequestServices ?? ServiceProvider;
} /// <summary>
/// 创建服务提供者Autofac
/// </summary>
/// <param name="nopConfig">Startup Nop configuration parameters</param>
/// <param name="services">Collection of service descriptors</param>
/// <param name="typeFinder">Type finder</param>
protected virtual IServiceProvider RegisterDependencies(IServiceCollection services)
{
var containerBuilder = new ContainerBuilder();
//注册引擎
containerBuilder.RegisterInstance(this).As<IEngine>().SingleInstance();
//数据库
containerBuilder.Register(context => new NopObjectContext(context.Resolve<DbContextOptions<NopObjectContext>>()))
.As<IDbContext>().InstancePerLifetimeScope();
//IOC
containerBuilder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();
containerBuilder.RegisterType<Sys_UserService>().As<ISys_UserService>().InstancePerLifetimeScope();//用一组注册的服务描述符填充Autofac容器构建器
containerBuilder.Populate(services); //创建服务提供者
_serviceProvider = new AutofacServiceProvider(containerBuilder.Build());
return _serviceProvider;
}
#endregion #region 方法
/// <summary>
/// Initialize engine
/// </summary>
/// <param name="services">Collection of service descriptors</param>
public void Initialize(IServiceCollection services)
{
//目前大多数APT供应商都需要TLS 1.2
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var provider = services.BuildServiceProvider();
var hostingEnvironment = provider.GetRequiredService<IHostingEnvironment>();
var mvcCoreBuilder = services.AddMvcCore();
}
/// <summary>
///添加配置服务
/// </summary>
/// <param name="services">Collection of service descriptors</param>
/// <param name="configuration">Configuration of the application</param>
/// <returns>Service provider</returns>
public IServiceProvider ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //数据库连接
var testConfig = services.BuildServiceProvider().GetRequiredService<TestConfig>();
services.AddDbContext<NopObjectContext>(options => options.UseLazyLoadingProxies().UseSqlServer(testConfig.SqlConnection));
services.AddEntityFrameworkSqlServer();
services.AddEntityFrameworkProxies();
//ioc
RegisterDependencies(services); services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
}); return _serviceProvider;
} /// <summary>
/// Configure HTTP request pipeline
/// </summary>
/// <param name="application">Builder for configuring an application's request pipeline</param>
public void ConfigureRequestPipeline(IApplicationBuilder application)
{
////find startup configurations provided by other assemblies
//var typeFinder = Resolve<ITypeFinder>();
//var startupConfigurations = typeFinder.FindClassesOfType<INopStartup>(); ////create and sort instances of startup configurations
//var instances = startupConfigurations
// //.Where(startup => PluginManager.FindPlugin(startup)?.Installed ?? true) //ignore not installed plugins
// .Select(startup => (INopStartup)Activator.CreateInstance(startup))
// .OrderBy(startup => startup.Order); ////configure request pipeline
//foreach (var instance in instances)
// instance.Configure(application);
} /// <summary>
/// Resolve dependency
/// </summary>
/// <typeparam name="T">Type of resolved service</typeparam>
/// <returns>Resolved service</returns>
public T Resolve<T>() where T : class
{
return (T)GetServiceProvider().GetRequiredService(typeof(T));
} /// <summary>
/// Resolve dependency
/// </summary>
/// <param name="type">Type of resolved service</param>
/// <returns>Resolved service</returns>
public object Resolve(Type type)
{
return GetServiceProvider().GetRequiredService(type);
} /// <summary>
/// Resolve dependencies
/// </summary>
/// <typeparam name="T">Type of resolved services</typeparam>
/// <returns>Collection of resolved services</returns>
public IEnumerable<T> ResolveAll<T>()
{
return (IEnumerable<T>)GetServiceProvider().GetServices(typeof(T));
} /// <summary>
/// Resolve unregistered service
/// </summary>
/// <param name="type">Type of service</param>
/// <returns>Resolved service</returns>
public virtual object ResolveUnregistered(Type type)
{
Exception innerException = null;
foreach (var constructor in type.GetConstructors())
{
try
{
//try to resolve constructor parameters
var parameters = constructor.GetParameters().Select(parameter =>
{
var service = Resolve(parameter.ParameterType);
if (service == null)
throw new Exception("Unknown dependency");
return service;
}); //all is ok, so create instance
return Activator.CreateInstance(type, parameters.ToArray());
}
catch (Exception ex)
{
innerException = ex;
}
} throw new Exception("No constructor was found that had all the dependencies satisfied.", innerException);
}
#endregion
}
IOC+EF+Core项目搭建IOC注入及框架(二)的更多相关文章
- IOC+EF+Core项目搭建EF封装(一)
添加应用Microsoft.EntityFrameworkCore:Microsoft.EntityFrameworkCore.Design:Microsoft.EntityFrameworkCore ...
- ASP.NET CORE 项目搭建(2022 年 3 月版)
ASP.NET CORE 项目搭建(2022 年 3 月版) 自读 沉淀了多年的技术积累,在 .NET FRAMEWORK 的框架下尝试造过自己的轮子. 摸索着闭门造过 基于 OWIN 服务后端. 摸 ...
- Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本)
Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本) 原创 2016年07月22日 10:33:51 23125 6月随着.NET COR ...
- IOC+EF+Core搭建项目框架(三)
/// <summary> /// 表示类别映射配置 /// </summary> public partial class sys_UserMap : NopEntityTy ...
- ASP.NET Core MVC+EF Core项目实战
项目背景 本项目参考于<Pro Entity Framework Core 2 for ASP.NET Core MVC>一书,项目内容为party邀请答复. 新建项目 本项目开发工具为V ...
- 《Asp.Net Core3 + Vue3入坑教程》-Net Core项目搭建与Swagger配置步骤
简介 <Asp.Net Core3 + Vue3入坑教程> 此教程仅适合新手入门或者前后端分离尝试者.可以根据图文一步一步进操作编码也可以选择直接查看源码.每一篇文章都有对应的源码 教程后 ...
- .net core项目搭建swagger接口实现简单增删改查
.net core搭建swagger 1,新建立.net core项目(这里不再细说) 2,引入NuGet程序包 3,建立项目之后在Startup类中配置swagger 这里我直接把代码贴出来: 在C ...
- .Net Core 项目引用本地类库方式(二)
上篇文章有详细的介绍.Net Core 项目中引用本地类库通过打包,然后Nugety引用方式,这里再介绍一种引用包的方式
- .NET Core项目部署到Linux(Centos7)(二)环境和软件的准备
目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...
随机推荐
- map初步(由ABBC--->A2BC)
1.题目: Given a string containing only 'A' - 'Z', we could encode it using the following method: 1. Ea ...
- ELK日志解决方案
1.方案整体设计 FileBeats+Logstash+ElasticSearch+Kibana 1)ElasticSearch 简称ES,用来做日志数据的存储,当然也可以存储其他数据, ES是互联网 ...
- DNS -- 快速清除DNS缓存
MAC: sudo dscacheutil -flushcache Linux: dnsmasq的是一个轻量级的DNS.TFTP和DHCP服务器.它的目的是给局域网提供配对的DNS和DHCP服务. d ...
- arcgis python获得别名
import arcpy # Create a Describe object from the GDB table. # desc = arcpy.Describe(r"C:\Users\ ...
- SQL-W3School-高级:SQL ALTER TABLE 语句
ylbtech-SQL-W3School-高级:SQL ALTER TABLE 语句 1.返回顶部 1. ALTER TABLE 语句 ALTER TABLE 语句用于在已有的表中添加.修改或删除列. ...
- mfc判断当前程序是否正在运行
HANDLE hMutex = CreateMutex(NULL,TRUE,_T("appName")); if(hMutex) { if(ERROR_ALREADY_EXISTS ...
- python多线程、线程锁
1.python多线程 多线程可以把空闲时间利用起来 比如有两个进程函数 func1.func2,func1函数里使用sleep休眠一定时间,如果使用单线程调用这两个函数,那么会顺序执行这两个函数 也 ...
- maven-mybatis代码生成
1.创建测试工程 选择maven Project 点击next 填写项目名称 点击 finish 项目创建完成 2.pom.xml <project xmlns="http://mav ...
- Chrome安装json格式化工具jsonView
1.下载jsonView 有条件的童鞋可以去谷歌商店下载安装https://chrome.google.com/webstore/detail/pmajcnnfhjcebiafkonednglookd ...
- 如何制作红蓝3d电影(详细教程)
自20世纪初以来,电影制作人一直试图通过制作3D电影来利用我们的双眼.现在,由于大量相对实惠的3D电视,你可以享受电影院以外的额外空间 - 你自己拍摄的视频.对于大预算的电影,电影摄影师使用两个相连的 ...