我的NopCommerce之旅(7): 依赖注入(IOC/DI)
一、基础介绍
public CountryController(ICountryService countryService,
IStateProvinceService stateProvinceService,
ILocalizationService localizationService,
IWorkContext workContext,
ICacheManager cacheManager)
{
this._countryService = countryService;
this._stateProvinceService = stateProvinceService;
this._localizationService = localizationService;
this._workContext = workContext;
this._cacheManager = cacheManager;
}
显然,你并没有在controller调用前,new一个ICountryService的对象给controller做参数,你也不知道该在哪去写这个调用。没关系,这些都交给系统处理,你不必理会,这就是依赖注入。
二、承上启下
上一篇大致分析了应用启动,而NopCommerce完成注册依赖就在初始化上下文部分。通过代码跟踪,即可发现Nop.Core.Infrastructure.NopEngine.RegisterDependencies()。
//initialize engine context 初始化上下文
EngineContext.Initialize(false);
/// <summary>
/// Initializes a static instance of the Nop factory.
/// </summary>
/// <param name="forceRecreate">Creates a new factory instance even though the factory has been previously initialized.</param>
[MethodImpl(MethodImplOptions.Synchronized)]
public static IEngine Initialize(bool forceRecreate)
{
if (Singleton<IEngine>.Instance == null || forceRecreate)
{
Singleton<IEngine>.Instance = new NopEngine(); var config = ConfigurationManager.GetSection("NopConfig") as NopConfig;
Singleton<IEngine>.Instance.Initialize(config);
}
return Singleton<IEngine>.Instance;
}
/// <summary>
/// Initialize components and plugins in the nop environment.
/// </summary>
/// <param name="config">Config</param>
public void Initialize(NopConfig config)
{
//register dependencies
RegisterDependencies(config); //startup tasks
if (!config.IgnoreStartupTasks)
{
RunStartupTasks();
} }
/// <summary>
/// Register dependencies
/// </summary>
/// <param name="config">Config</param>
protected virtual void RegisterDependencies(NopConfig config)
{
var builder = new ContainerBuilder();
var container = builder.Build();
this._containerManager = new ContainerManager(container); //we create new instance of ContainerBuilder
//because Build() or Update() method can only be called once on a ContainerBuilder. //dependencies
var typeFinder = new WebAppTypeFinder();
builder = new ContainerBuilder();
builder.RegisterInstance(config).As<NopConfig>().SingleInstance();
builder.RegisterInstance(this).As<IEngine>().SingleInstance();
builder.RegisterInstance(typeFinder).As<ITypeFinder>().SingleInstance();
builder.Update(container); //register dependencies provided by other assemblies
builder = new ContainerBuilder();
var drTypes = typeFinder.FindClassesOfType<IDependencyRegistrar>();
var drInstances = new List<IDependencyRegistrar>();
foreach (var drType in drTypes)
drInstances.Add((IDependencyRegistrar) Activator.CreateInstance(drType));
//sort
drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList();
foreach (var dependencyRegistrar in drInstances)
dependencyRegistrar.Register(builder, typeFinder, config);通过反射,按顺序注册依赖
builder.Update(container); //set dependency resolver
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
三、NopCommerce的结构分析
1.分析方法
在vs里Solution Explorer的查找栏输入DependencyRegistrar,即可看到所有实现DependencyRegistrar()方法的。
2.总结
2.1 Nop.Core定义了接口;
2.2 Plugins注册自己需要的类;
2.3 Nop.Admin和Nop.Web注册Controller所要使用的缓存类;
2.4 Nop.Web.Framework注册了NopCommerce的核心类。
四、代码分析
1.这里主要分析Nop.Web.Framework的DependencyRegistrar()
1.1.注册http上下文;
1.2.注册web helper、user agent helper;
1.3.注册mvc的controllers;
1.4.注册数据层类,如dbcontext,manager,repository,供持久化层的操作;
1.5.注册插件plugins;
1.6.注册缓存管理的相关类;
1.7.注册work context和store context;
1.8.注册业务层services,部分需注册缓存参数,可以看到WithParameter( ResolvedParameter.ForNamed< ICacheManager >("nop_cache_static" ));
1.9.注册用户事件。
2.代码如下
/// <summary>
/// Register services and interfaces
/// </summary>
/// <param name="builder">Container builder</param>
/// <param name="typeFinder">Type finder</param>
/// <param name="config">Config</param>
public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
{
//HTTP context and other related stuff
builder.Register(c =>
//register FakeHttpContext when HttpContext is not available
HttpContext.Current != null ?
(new HttpContextWrapper(HttpContext.Current) as HttpContextBase) :
(new FakeHttpContext("~/") as HttpContextBase))
.As<HttpContextBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Request)
.As<HttpRequestBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Response)
.As<HttpResponseBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Server)
.As<HttpServerUtilityBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Session)
.As<HttpSessionStateBase>()
.InstancePerLifetimeScope(); //web helper
builder.RegisterType<WebHelper>().As<IWebHelper>().InstancePerLifetimeScope();
//user agent helper
builder.RegisterType<UserAgentHelper>().As<IUserAgentHelper>().InstancePerLifetimeScope(); //controllers
builder.RegisterControllers(typeFinder.GetAssemblies().ToArray()); //data layer
var dataSettingsManager = new DataSettingsManager();
var dataProviderSettings = dataSettingsManager.LoadSettings();
builder.Register(c => dataSettingsManager.LoadSettings()).As<DataSettings>();
builder.Register(x => new EfDataProviderManager(x.Resolve<DataSettings>())).As<BaseDataProviderManager>().InstancePerDependency(); builder.Register(x => x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IDataProvider>().InstancePerDependency(); if (dataProviderSettings != null && dataProviderSettings.IsValid())
{
var efDataProviderManager = new EfDataProviderManager(dataSettingsManager.LoadSettings());
var dataProvider = efDataProviderManager.LoadDataProvider();
dataProvider.InitConnectionFactory(); builder.Register<IDbContext>(c => new NopObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();
}
else
{
builder.Register<IDbContext>(c => new NopObjectContext(dataSettingsManager.LoadSettings().DataConnectionString)).InstancePerLifetimeScope();
} builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope(); //plugins
builder.RegisterType<PluginFinder>().As<IPluginFinder>().InstancePerLifetimeScope();
builder.RegisterType<OfficialFeedManager>().As<IOfficialFeedManager>().InstancePerLifetimeScope(); //cache managers
if (config.RedisCachingEnabled)
{
builder.RegisterType<RedisCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").InstancePerLifetimeScope();
}
else
{
builder.RegisterType<MemoryCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").SingleInstance();
}
builder.RegisterType<PerRequestCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_per_request").InstancePerLifetimeScope(); if (config.RunOnAzureWebsites)
{
builder.RegisterType<AzureWebsitesMachineNameProvider>().As<IMachineNameProvider>().SingleInstance();
}
else
{
builder.RegisterType<DefaultMachineNameProvider>().As<IMachineNameProvider>().SingleInstance();
} //work context
builder.RegisterType<WebWorkContext>().As<IWorkContext>().InstancePerLifetimeScope();
//store context
builder.RegisterType<WebStoreContext>().As<IStoreContext>().InstancePerLifetimeScope(); //services
builder.RegisterType<BackInStockSubscriptionService>().As<IBackInStockSubscriptionService>().InstancePerLifetimeScope();
builder.RegisterType<CategoryService>().As<ICategoryService>().InstancePerLifetimeScope();
builder.RegisterType<CompareProductsService>().As<ICompareProductsService>().InstancePerLifetimeScope();
builder.RegisterType<RecentlyViewedProductsService>().As<IRecentlyViewedProductsService>().InstancePerLifetimeScope();
builder.RegisterType<ManufacturerService>().As<IManufacturerService>().InstancePerLifetimeScope();
builder.RegisterType<PriceFormatter>().As<IPriceFormatter>().InstancePerLifetimeScope();
builder.RegisterType<ProductAttributeFormatter>().As<IProductAttributeFormatter>().InstancePerLifetimeScope();
builder.RegisterType<ProductAttributeParser>().As<IProductAttributeParser>().InstancePerLifetimeScope();
builder.RegisterType<ProductAttributeService>().As<IProductAttributeService>().InstancePerLifetimeScope();
builder.RegisterType<ProductService>().As<IProductService>().InstancePerLifetimeScope();
builder.RegisterType<CopyProductService>().As<ICopyProductService>().InstancePerLifetimeScope();
builder.RegisterType<SpecificationAttributeService>().As<ISpecificationAttributeService>().InstancePerLifetimeScope();
builder.RegisterType<ProductTemplateService>().As<IProductTemplateService>().InstancePerLifetimeScope();
builder.RegisterType<CategoryTemplateService>().As<ICategoryTemplateService>().InstancePerLifetimeScope();
builder.RegisterType<ManufacturerTemplateService>().As<IManufacturerTemplateService>().InstancePerLifetimeScope();
builder.RegisterType<TopicTemplateService>().As<ITopicTemplateService>().InstancePerLifetimeScope();
//use static cache (between HTTP requests)
builder.RegisterType<ProductTagService>().As<IProductTagService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope(); builder.RegisterType<AddressAttributeFormatter>().As<IAddressAttributeFormatter>().InstancePerLifetimeScope();
builder.RegisterType<AddressAttributeParser>().As<IAddressAttributeParser>().InstancePerLifetimeScope();
builder.RegisterType<AddressAttributeService>().As<IAddressAttributeService>().InstancePerLifetimeScope();
builder.RegisterType<AddressService>().As<IAddressService>().InstancePerLifetimeScope();
builder.RegisterType<AffiliateService>().As<IAffiliateService>().InstancePerLifetimeScope();
builder.RegisterType<VendorService>().As<IVendorService>().InstancePerLifetimeScope();
builder.RegisterType<SearchTermService>().As<ISearchTermService>().InstancePerLifetimeScope();
builder.RegisterType<GenericAttributeService>().As<IGenericAttributeService>().InstancePerLifetimeScope();
builder.RegisterType<FulltextService>().As<IFulltextService>().InstancePerLifetimeScope();
builder.RegisterType<MaintenanceService>().As<IMaintenanceService>().InstancePerLifetimeScope(); builder.RegisterType<CustomerAttributeParser>().As<ICustomerAttributeParser>().InstancePerLifetimeScope();
builder.RegisterType<CustomerAttributeService>().As<ICustomerAttributeService>().InstancePerLifetimeScope();
builder.RegisterType<CustomerService>().As<ICustomerService>().InstancePerLifetimeScope();
builder.RegisterType<CustomerRegistrationService>().As<ICustomerRegistrationService>().InstancePerLifetimeScope();
builder.RegisterType<CustomerReportService>().As<ICustomerReportService>().InstancePerLifetimeScope(); //use static cache (between HTTP requests)
builder.RegisterType<PermissionService>().As<IPermissionService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope();
//use static cache (between HTTP requests)
builder.RegisterType<AclService>().As<IAclService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope();
//use static cache (between HTTP requests)
builder.RegisterType<PriceCalculationService>().As<IPriceCalculationService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope(); builder.RegisterType<GeoLookupService>().As<IGeoLookupService>().InstancePerLifetimeScope();
builder.RegisterType<CountryService>().As<ICountryService>().InstancePerLifetimeScope();
builder.RegisterType<CurrencyService>().As<ICurrencyService>().InstancePerLifetimeScope();
builder.RegisterType<MeasureService>().As<IMeasureService>().InstancePerLifetimeScope();
builder.RegisterType<StateProvinceService>().As<IStateProvinceService>().InstancePerLifetimeScope(); builder.RegisterType<StoreService>().As<IStoreService>().InstancePerLifetimeScope();
//use static cache (between HTTP requests)
builder.RegisterType<StoreMappingService>().As<IStoreMappingService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope(); builder.RegisterType<DiscountService>().As<IDiscountService>().InstancePerLifetimeScope(); //use static cache (between HTTP requests)
builder.RegisterType<SettingService>().As<ISettingService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope();
builder.RegisterSource(new SettingsSource()); //use static cache (between HTTP requests)
builder.RegisterType<LocalizationService>().As<ILocalizationService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope(); //use static cache (between HTTP requests)
builder.RegisterType<LocalizedEntityService>().As<ILocalizedEntityService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope();
builder.RegisterType<LanguageService>().As<ILanguageService>().InstancePerLifetimeScope(); builder.RegisterType<DownloadService>().As<IDownloadService>().InstancePerLifetimeScope();
//picture service
var useAzureBlobStorage = !String.IsNullOrEmpty(config.AzureBlobStorageConnectionString);
if (useAzureBlobStorage)
{
//Windows Azure BLOB
builder.RegisterType<AzurePictureService>().As<IPictureService>().InstancePerLifetimeScope();
}
else
{
//standard file system
builder.RegisterType<PictureService>().As<IPictureService>().InstancePerLifetimeScope();
} builder.RegisterType<MessageTemplateService>().As<IMessageTemplateService>().InstancePerLifetimeScope();
builder.RegisterType<QueuedEmailService>().As<IQueuedEmailService>().InstancePerLifetimeScope();
builder.RegisterType<NewsLetterSubscriptionService>().As<INewsLetterSubscriptionService>().InstancePerLifetimeScope();
builder.RegisterType<CampaignService>().As<ICampaignService>().InstancePerLifetimeScope();
builder.RegisterType<EmailAccountService>().As<IEmailAccountService>().InstancePerLifetimeScope();
builder.RegisterType<WorkflowMessageService>().As<IWorkflowMessageService>().InstancePerLifetimeScope();
builder.RegisterType<MessageTokenProvider>().As<IMessageTokenProvider>().InstancePerLifetimeScope();
builder.RegisterType<Tokenizer>().As<ITokenizer>().InstancePerLifetimeScope();
builder.RegisterType<EmailSender>().As<IEmailSender>().InstancePerLifetimeScope(); builder.RegisterType<CheckoutAttributeFormatter>().As<ICheckoutAttributeFormatter>().InstancePerLifetimeScope();
builder.RegisterType<CheckoutAttributeParser>().As<ICheckoutAttributeParser>().InstancePerLifetimeScope();
builder.RegisterType<CheckoutAttributeService>().As<ICheckoutAttributeService>().InstancePerLifetimeScope();
builder.RegisterType<GiftCardService>().As<IGiftCardService>().InstancePerLifetimeScope();
builder.RegisterType<OrderService>().As<IOrderService>().InstancePerLifetimeScope();
builder.RegisterType<OrderReportService>().As<IOrderReportService>().InstancePerLifetimeScope();
builder.RegisterType<OrderProcessingService>().As<IOrderProcessingService>().InstancePerLifetimeScope();
builder.RegisterType<OrderTotalCalculationService>().As<IOrderTotalCalculationService>().InstancePerLifetimeScope();
builder.RegisterType<ReturnRequestService>().As<IReturnRequestService>().InstancePerLifetimeScope();
builder.RegisterType<RewardPointService>().As<IRewardPointService>().InstancePerLifetimeScope();
builder.RegisterType<ShoppingCartService>().As<IShoppingCartService>().InstancePerLifetimeScope(); builder.RegisterType<PaymentService>().As<IPaymentService>().InstancePerLifetimeScope(); builder.RegisterType<EncryptionService>().As<IEncryptionService>().InstancePerLifetimeScope();
builder.RegisterType<FormsAuthenticationService>().As<IAuthenticationService>().InstancePerLifetimeScope(); //use static cache (between HTTP requests)
builder.RegisterType<UrlRecordService>().As<IUrlRecordService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope(); builder.RegisterType<ShipmentService>().As<IShipmentService>().InstancePerLifetimeScope();
builder.RegisterType<ShippingService>().As<IShippingService>().InstancePerLifetimeScope(); builder.RegisterType<TaxCategoryService>().As<ITaxCategoryService>().InstancePerLifetimeScope();
builder.RegisterType<TaxService>().As<ITaxService>().InstancePerLifetimeScope(); builder.RegisterType<DefaultLogger>().As<ILogger>().InstancePerLifetimeScope(); //use static cache (between HTTP requests)
builder.RegisterType<CustomerActivityService>().As<ICustomerActivityService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope(); bool databaseInstalled = DataSettingsHelper.DatabaseIsInstalled();
if (!databaseInstalled)
{
//installation service
if (config.UseFastInstallationService)
{
builder.RegisterType<SqlFileInstallationService>().As<IInstallationService>().InstancePerLifetimeScope();
}
else
{
builder.RegisterType<CodeFirstInstallationService>().As<IInstallationService>().InstancePerLifetimeScope();
}
} builder.RegisterType<ForumService>().As<IForumService>().InstancePerLifetimeScope(); builder.RegisterType<PollService>().As<IPollService>().InstancePerLifetimeScope();
builder.RegisterType<BlogService>().As<IBlogService>().InstancePerLifetimeScope();
builder.RegisterType<WidgetService>().As<IWidgetService>().InstancePerLifetimeScope();
builder.RegisterType<TopicService>().As<ITopicService>().InstancePerLifetimeScope();
builder.RegisterType<NewsService>().As<INewsService>().InstancePerLifetimeScope(); builder.RegisterType<DateTimeHelper>().As<IDateTimeHelper>().InstancePerLifetimeScope();
builder.RegisterType<SitemapGenerator>().As<ISitemapGenerator>().InstancePerLifetimeScope();
builder.RegisterType<PageHeadBuilder>().As<IPageHeadBuilder>().InstancePerLifetimeScope(); builder.RegisterType<ScheduleTaskService>().As<IScheduleTaskService>().InstancePerLifetimeScope(); builder.RegisterType<ExportManager>().As<IExportManager>().InstancePerLifetimeScope();
builder.RegisterType<ImportManager>().As<IImportManager>().InstancePerLifetimeScope();
builder.RegisterType<PdfService>().As<IPdfService>().InstancePerLifetimeScope();
builder.RegisterType<ThemeProvider>().As<IThemeProvider>().InstancePerLifetimeScope();
builder.RegisterType<ThemeContext>().As<IThemeContext>().InstancePerLifetimeScope(); builder.RegisterType<ExternalAuthorizer>().As<IExternalAuthorizer>().InstancePerLifetimeScope();
builder.RegisterType<OpenAuthenticationService>().As<IOpenAuthenticationService>().InstancePerLifetimeScope(); builder.RegisterType<RoutePublisher>().As<IRoutePublisher>().SingleInstance(); //Register event consumers
var consumers = typeFinder.FindClassesOfType(typeof(IConsumer<>)).ToList();
foreach (var consumer in consumers)
{
builder.RegisterType(consumer)
.As(consumer.FindInterfaces((type, criteria) =>
{
var isMatch = type.IsGenericType && ((Type)criteria).IsAssignableFrom(type.GetGenericTypeDefinition());
return isMatch;
}, typeof(IConsumer<>)))
.InstancePerLifetimeScope();
}
builder.RegisterType<EventPublisher>().As<IEventPublisher>().SingleInstance();
builder.RegisterType<SubscriptionService>().As<ISubscriptionService>().SingleInstance(); }
我的NopCommerce之旅(7): 依赖注入(IOC/DI)的更多相关文章
- 关于依赖注入IOC/DI的感想
之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...
- 控制反转( IoC)和依赖注入(DI)
控制反转( IoC)和依赖注入(DI) tags: 容器 依赖注入 IOC DI 控制反转 引言:如果你看过一些框架的源码或者手册,像是laravel或者tp5之类的,应该会提到容器,依赖注入,控制反 ...
- ASP.NET Core中的依赖注入(2):依赖注入(DI)
IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...
- 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)
举例:在每天的日常生活中,我们离不开水,电,气.在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭.而城市化之后,人们从这些琐事中解放了出来,城市中出 ...
- Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)
一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.S ...
- 控制反转(IOC)和依赖注入(DI)的区别
IOC inversion of control 控制反转 DI Dependency Injection 依赖注入 要理解这两个概念,首先要搞清楚以下几个问题: 参与者都有谁? 依赖:谁 ...
- Spring的依赖注入(DI)三种方式
Spring依赖注入(DI)的三种方式,分别为: 1. 接口注入 2. Setter方法注入 3. 构造方法注入 下面介绍一下这三种依赖注入在Spring中是怎么样实现的. 首先我们需要以下几个 ...
- Spring 反转控制(IOC) 依赖注入(DI)
简单的理解: 之前是我为了完成业务A 需要某个对象B的支持 那么我在这个业务A中就会创建一个对象B使用,说白了就是我根据需求来控制对象B, 而spring的ioc把对象B的控制权从业务A手中拿到自己手 ...
- 添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
添加EF上下文对象,添加接口.实现类以及无处不在的依赖注入(DI) 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建 ...
随机推荐
- SpringMVC 注释@PathVariable
@PathVariable 是用来获得请求url中的动态参数的: @ResponseBody @RequestMapping(value="/pointUpload/{userid}&quo ...
- Java丨时间判断谁前谁后
直奔主题: String date_str1 = "2016-06-02 23:03:123"; String date_str2 = "2016-06-03 03:03 ...
- CodeForces768B:Code For 1 (分治)
Jon fought bravely to rescue the wildlings who were attacked by the white-walkers at Hardhome. On hi ...
- poj2828 Buy Tickets——倒序处理
题目:http://poj.org/problem?id=2828 这题可以倒序来做,因为越靠后的人实际上优先级越高: 用0和1表示这个位置上是否已经有人,0表示有,1表示没有,这样树状数组维护前缀和 ...
- ASP.NET Core会议管理平台实战_1、开篇介绍
用到四个数据库
- Ubuntu下对与rtl8723be网卡频繁断网问题解决
linux下对于rtl系列的无线网卡,大多数网友都在吐槽,总是频繁的掉网,就此将自己在网上安装时的经验写下. 1.下载网卡驱动,其中包含rtl的大多数包 sudo apt-get install li ...
- VS Supercharger插件
一.前言 Supercharger 是 VS 的一款插件,针对代码进行优化和着色,便于观察和区分. 二.下载及安装 下载的 URL 如下:Supercharger 下载地址 点击下载,下载完成以后,那 ...
- 在ANGULAR6中使用Echarts的正确方式之一
这里的正确指的是不会在运行过程中报错,不会再prod模式下编译报错,不会再AOT模式下编译报错 个人环境说明: { "name": "angular-for-echart ...
- tableView刷新指定的cell 或section和滚动到指定的位置
转自:http://blog.csdn.net/tianyou_code/article/details/54426494 //一个section刷新 NSIndexSet *indexSet=[[N ...
- Codeforces Round #439 (Div. 2)C - The Intriguing Obsession(简单dp)
传送门 题意 给出三个集合,每个集合的元素数量为a,b,c,现在需要连边,满足集合内元素不可达或最短路为3,求可行方案数 分析 设dp[i][j]为a集合元素为i个,b集合元素为j个的可行方案,易知( ...