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 }

 

posted @ 2019-08-12 11:35  世人皆萌  阅读(1092)  评论(0编辑  收藏  举报