/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.
This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Everest.Library.Reflection;
using Everest.Library.Providers.Caching;
using Everest.Library.ExtensionMethod;
namespace Everest.CmsServices.Extension{
/// <summary>
/// The standard plugin type resolver.
/// </summary>
/// <typeparam name="T"></typeparam>
public class StandardPluginResolver<T> : IPluginResolver<T>
{
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="StandardPluginResolver<T>"/> class.
/// </summary>
/// <param name="path">The path.</param>
public StandardPluginResolver(string path)
{
this.Path = path;
FileExtensions.EnsureDirtectoryExists(path);
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
AssemblyName assemblyName = new AssemblyName(args.Name);
string[] files = Directory.GetFiles(Path, string.Format("{0}.dll", assemblyName.Name), SearchOption.AllDirectories);
if (files.Length > 0)
{
Assembly assembly = AssemblyHelper.LoadAssembly(files[files.Length - 1]);
return assembly;
}
return null;
}
public static object lockHelper = new object();
/// <summary>
/// Gets the plugins.
/// </summary>
/// <returns></returns>
public Dictionary<Type, string> GetPlugins()
{
string cacheKey = "plugins-" + Path;
if (CacheManager.Get(cacheKey) == null)
{
lock (lockHelper)
{
if (CacheManager.Get(cacheKey) == null)
{
Dictionary<Type, string> dic;
if (!Directory.Exists(Path))
{
dic = new Dictionary<Type, string>();
}
else
{
dic = GetPluginsFromDirectory(Path);
}
CacheManager.Add(cacheKey, dic, CacheItemPriority.Normal, null, new DirectoryDependency(Path));
}
}
}
return (Dictionary<Type, string>)CacheManager.Get(cacheKey);
}
/// <summary>
/// Gets the plugins from directory.
/// </summary>
/// <param name="path">The path.</param>
/// <returns></returns>
private Dictionary<Type, string> GetPluginsFromDirectory(string path)
{
string[] assemblyFiles = Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories);
Dictionary<Type, string> types = new Dictionary<Type, string>();
foreach (var file in assemblyFiles)
{
Assembly assembly = AssemblyHelper.LoadAssembly(file);
Type targetType = typeof(T);
foreach (var type in assembly.GetTypes())
{
if (targetType.IsAssignableFrom(type) && !types.ContainsKey(type))
{
types.Add(type, CmsGlobal.ToRelativePath(file));
}
}
}
return types;
}
#region IPluginResolver Members
/// <summary>
/// Resolves the specified type name.
/// </summary>
/// <param name="typeName">Name of the type.</param>
/// <returns></returns>
public T Resolve(string typeName)
{
T o = default(T);
foreach (var type in GetPlugins().Keys)
{
if (type.FullName == typeName)
{
o = (T)Activator.CreateInstance(type);
}
}
return o;
}
/// <summary>
/// Resolves the specified type names.
/// </summary>
/// <param name="typeNames">The type names.</param>
/// <returns></returns>
public IEnumerable<T> Resolve(IEnumerable<string> typeNames)
{
List<T> list = new List<T>();
foreach (var type in GetPlugins().Keys)
{
if (typeNames.Contains(type.FullName))
{
list.Add((T)Activator.CreateInstance(type));
}
}
return list;
}
#endregion
#region IPluginResolver<T> Members
/// <summary>
/// Resolves the type.
/// </summary>
/// <param name="predicate">The predicate.</param>
/// <param name="directory">The directory.</param>
/// <returns></returns>
public T Resolve(Func<Type, Type> predicate, out string directory)
{
directory = string.Empty;
Dictionary<Type, string> plugins = GetPlugins();
foreach (var type in plugins.Keys)
{
Type filtered = predicate(type);
if (filtered != null)
{
directory = plugins[type];
return (T)Activator.CreateInstance(filtered);
}
}
return default(T);
}
#endregion
#region IPluginResolver<T> Members
public IDictionary<Type, string> ResolveAll()
{
return this.GetPlugins();
}
#endregion
}
}
|