我的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 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建 ...
随机推荐
- codeforces 665A A. Buses Between Cities(水题)
题目链接: A. Buses Between Cities time limit per test 1 second memory limit per test 256 megabytes input ...
- ZIP伪加密(deprecated)
ZIP伪加密 经过伪加密的apk,改成zip格式打开会发现里面的文件都经过了加密. APK实际上是Zip压缩文件,但是Android系统在解析APK文件时,和传统的解压压缩软件在解析Zip文件时存在差 ...
- debugs
import os def get_nova_credentials_v2(): d = {} d['version'] = '2.0' d['username'] = os.environ['OS_ ...
- Java 类加载器的作用
深入探讨 Java 类加载器 成 富, 软件工程师, IBM 中国软件开发中心 成富任职于 IBM 中国软件开发中心,目前在 Lotus 部门从事 IBM Mashup Center 的开发工作.他毕 ...
- awk用法总结
简介 awk的命名来自于他的三位创始人Alfred Aho .Peter Weinberger 和 Brian Kernighan 的姓氏的首字母. 有多种版本:New awk(nawk),GNU a ...
- 1118 Birds in Forest (25 分)
Some scientists took pictures of thousands of birds in a forest. Assume that all the birds appear in ...
- 1004 Counting Leaves (30 分)
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family member ...
- layui 关闭当前窗口,刷新父级页面
关闭当前窗口 layer.close(layer.index); 刷新页面 window.parent.location.reload();
- 洛谷P2505 [HAOI2012]道路(最短路计数)
传送门 早上模拟赛考这题,结果竟然看错题目了orz 然后下午看完题解自己做的时候空间开小了白WA了好久orz 首先,如果以$S$为起点,一条边$(u,v)$在最短路上,则$dis[u]+edge[i] ...
- [Xcode 实际操作]二、视图与手势-(11)UITapGestureRecognizer手势之长按
目录:[Swift]Xcode实际操作 本文将演示使用视图的长按手势,完成视图的交互功能. import UIKit class ViewController: UIViewController { ...