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. ...
随机推荐
- hystrix(一) 简单使用, 以及动态配置更新
本文转载自https://my.oschina.net/u/1169457/blog/1787414 hystrix 简单使用, 以及动态配置更新 概述 只介绍同步模式下简单的使用, 有助于快速接入, ...
- MapReduce shuffle的过程分析
shuffle阶段其实就是多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点上. Map端: 1.在map端首先接触的是InputSplit,在InputSplit中含有D ...
- spaCy 第一篇:核心类型
spaCy 是一个号称工业级的自然语言处理工具包,最核心的数据结构是Doc和Vocab.Doc对象包含Token的序列和Token的注释(Annotation),Vocab对象是spaCy使用的词汇表 ...
- 我的新书,ArcGIS从0到1,京东接受预定,有160个视频,851分钟
我的新书,ArcGIS从0到1,京东接受预定,8月08日至08月16日发货https://item.jd.com/53669213250.html当当网 http://product.dangdan ...
- mongoose 实现 增、删、改、查
mongoose常用的API 增 save是一个实例方法,使用时需要先 new Model() 来实例化 //保存一个用户信息,userobj为你创建的文档对象模型里的字段,需正确对应传入 const ...
- count(1) 与 count(*) 比较
1. count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 从执行计划来看,count(1)和count(*)的效 ...
- maven打包遇到错误,Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.1:test
对Pom文件进行配置(亲自尝试,已成功解决) <build> <plugins> <plugin> <groupId>org.apache.maven. ...
- 性能优化 | JVM性能调优篇——来自阿里P7的经验总结
VM 调优概述: 性能定义: 吞吐量 - 指不考虑 GC 引起的停顿时间或内存消耗,垃圾收集器能支撑应用达到的最高性能指标. 延迟 - 其度量标准是缩短由于垃圾啊收集引起的停顿时间或者完全消除因垃圾收 ...
- kotlin中集合
fun main(arg: Array<String>) { //可读写的集合创建 val mutableListOf1 = mutableListOf<Int>(1, 2, ...
- react 组件创建
/** * 数据屏蔽 * Created by 2016-12-02. */ import React, {Component} from 'react'; export default class ...