上一章说到,GetWidgetZones()方法返回了IWidgetPlugin接口, 那么,IWidgetPlugin这些插件如何注册的呢,这就要看下面了:
路径:\Presentation\Nop.Web\Global.asax.cs
protected void Application_Start()
{
//initialize engine context
EngineContext.Initialize(false);
...
EngineContext.Initialize(false);中注册了所有的插件,下面我们具体跟踪一下是怎么注册的:
路径:\Libraries\Nop.Core\Infrastructure\EngineContext.cs
/// <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)
{
var config = ConfigurationManager.GetSection("NopConfig") as NopConfig;
Singleton<IEngine>.Instance = CreateEngineInstance(config);
Singleton<IEngine>.Instance.Initialize(config);
}
return Singleton<IEngine>.Instance;
}
CreateEngineInstance(NopConfig config)方法如下:
/// <summary>
/// Creates a factory instance and adds a http application injecting facility.
/// </summary>
/// <param name="config">Config</param>
/// <returns>New engine instance</returns>
protected static IEngine CreateEngineInstance(NopConfig config)
{
if (config != null && !string.IsNullOrEmpty(config.EngineType))
{
var engineType = Type.GetType(config.EngineType);
if (engineType == null)
throw new ConfigurationErrorsException("The type '" + config.EngineType + "' could not be found. Please check the configuration at /configuration/nop/engine[@engineType] or check for missing assemblies.");
if (!typeof(IEngine).IsAssignableFrom(engineType))
throw new ConfigurationErrorsException("The type '" + engineType + "' doesn't implement 'Nop.Core.Infrastructure.IEngine' and cannot be configured in /configuration/nop/engine[@engineType] for that purpose.");
return Activator.CreateInstance(engineType) as IEngine;
}
return new NopEngine();
}
由于配置文件中Engine Type为空(<Engine Type="" />)所以,返回的实例是new NopEngine();所以Singleton<IEngine>.Instance.Initialize(config)调用的是:
路径:\Libraries\Nop.Core\Infrastructure\NopEngine.cs
/// <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();
}
}
然后我们看一下RegisterDependencies(config)这个方法:
/// <summary>
/// Register dependencies
/// </summary>
/// <param name="config">Config</param>
protected virtual void RegisterDependencies(NopConfig config)
{
var builder = new ContainerBuilder();
var container = builder.Build();
//we create new instance of ContainerBuilder
//because Build() or Update() method can only be called once on a ContainerBuilder.
//dependencies
var typeFinder = new WebAppTypeFinder(config);
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);
builder.Update(container);
this._containerManager = new ContainerManager(container);
//set dependency resolver
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
这里使用autofac注册了IDependencyRegistrar类型,根据Order成员变量进行排序后,循环这些实现类并调用 void Register(ContainerBuilder builder, ITypeFinder typeFinder)方法来进行注册。我查找了一下所有实现接口的方法:
\nopCommerce\Presentation\Nop.Web\Infrastructure\DependencyRegistrar.cs(11): public class DependencyRegistrar : IDependencyRegistrar
\nopCommerce\Presentation\Nop.Web.Framework\DependencyRegistrar.cs(58): public class DependencyRegistrar : IDependencyRegistrar
\nopCommerce\Presentation\Nop.Web\Administration\Infrastructure\DependencyRegistrar.cs(10): public class DependencyRegistrar : IDependencyRegistrar
\nopCommerce\Plugins\Nop.Plugin.Feed.Froogle\DependencyRegistrar.cs(14): public class DependencyRegis