Merge with default

This commit is contained in:
ebr11 Eric Reed spam
2012-09-20 13:54:37 -04:00
70 changed files with 3384 additions and 30 deletions

View File

@@ -1,5 +1,6 @@
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Logging;
using MediaBrowser.Common.Mef;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Net.Handlers;
using MediaBrowser.Common.Plugins;
@@ -10,6 +11,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -88,6 +90,9 @@ namespace MediaBrowser.Common.Kernel
/// </summary>
private IDisposable HttpListener { get; set; }
/// <summary>
/// Gets the MEF CompositionContainer
/// </summary>
private CompositionContainer CompositionContainer { get; set; }
protected virtual string HttpServerUrlPrefix
@@ -184,18 +189,20 @@ namespace MediaBrowser.Common.Kernel
// This will prevent the .dll file from getting locked, and allow us to replace it when needed
IEnumerable<Assembly> pluginAssemblies = Directory.GetFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly).Select(f => Assembly.Load(File.ReadAllBytes((f))));
var catalog = new AggregateCatalog(pluginAssemblies.Select(a => new AssemblyCatalog(a)));
var catalogs = new List<ComposablePartCatalog>();
catalogs.AddRange(pluginAssemblies.Select(a => new AssemblyCatalog(a)));
// Include composable parts in the Common assembly
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
if (includeCurrentAssembly)
{
// Include composable parts in the subclass assembly
catalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
catalogs.Add(new AssemblyCatalog(GetType().Assembly));
}
return new CompositionContainer(catalog);
return MefUtils.GetSafeCompositionContainer(catalogs);
}
/// <summary>

View File

@@ -87,6 +87,7 @@
<Compile Include="Logging\BaseLogger.cs" />
<Compile Include="Logging\LogSeverity.cs" />
<Compile Include="Logging\TraceFileLogger.cs" />
<Compile Include="Mef\MefUtils.cs" />
<Compile Include="Net\Handlers\StaticFileHandler.cs" />
<Compile Include="Net\MimeTypes.cs" />
<Compile Include="Plugins\BaseTheme.cs" />

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Reflection;
namespace MediaBrowser.Common.Mef
{
public static class MefUtils
{
/// <summary>
/// Plugins that live on both the server and UI are going to have references to assemblies from both sides.
/// But looks for Parts on one side, it will throw an exception when it seems Types from the other side that it doesn't have a reference to.
/// For example, a plugin provides a Resolver. When MEF runs in the UI, it will throw an exception when it sees the resolver because there won't be a reference to the base class.
/// This method will catch those exceptions while retining the list of Types that MEF is able to resolve.
/// </summary>
public static CompositionContainer GetSafeCompositionContainer(IEnumerable<ComposablePartCatalog> catalogs)
{
var newList = new List<ComposablePartCatalog>();
// Go through each Catalog
foreach (var catalog in catalogs)
{
try
{
// Try to have MEF find Parts
catalog.Parts.ToArray();
// If it succeeds we can use the entire catalog
newList.Add(catalog);
}
catch (ReflectionTypeLoadException ex)
{
// If it fails we can still get a list of the Types it was able to resolve and create TypeCatalogs
var typeCatalogs = ex.Types.Where(t => t != null).Select(t => new TypeCatalog(t));
newList.AddRange(typeCatalogs);
}
}
return new CompositionContainer(new AggregateCatalog(newList));
}
}
}

View File

@@ -4,6 +4,7 @@ using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Plugins;
using System;
using System.IO;
using System.Reflection;
namespace MediaBrowser.Common.Plugins
{
@@ -12,7 +13,7 @@ namespace MediaBrowser.Common.Plugins
/// </summary>
public abstract class BasePlugin : IDisposable
{
private IKernel Kernel { get; set; }
protected IKernel Kernel { get; private set; }
/// <summary>
/// Gets or sets the plugin's current context

View File

@@ -1,4 +1,12 @@

using MediaBrowser.Common.Mef;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Windows;
using System.Windows.Controls;
namespace MediaBrowser.Common.Plugins
{
public abstract class BaseTheme : BasePlugin
@@ -10,5 +18,61 @@ namespace MediaBrowser.Common.Plugins
return true;
}
}
/// <summary>
/// Gets the MEF CompositionContainer
/// </summary>
private CompositionContainer CompositionContainer { get; set; }
/// <summary>
/// Gets the list of global resources
/// </summary>
[ImportMany(typeof(ResourceDictionary))]
public IEnumerable<ResourceDictionary> GlobalResources { get; private set; }
/// <summary>
/// Gets the list of pages
/// </summary>
[ImportMany(typeof(Page))]
public IEnumerable<Page> Pages { get; private set; }
/// <summary>
/// Gets the pack Uri of the Login page
/// </summary>
public abstract Uri LoginPageUri { get; }
protected override void InitializeInUi()
{
base.InitializeInUi();
ComposeParts();
}
private void ComposeParts()
{
var catalog = new AssemblyCatalog(GetType().Assembly);
CompositionContainer = MefUtils.GetSafeCompositionContainer(new ComposablePartCatalog[] { catalog });
CompositionContainer.ComposeParts(this);
CompositionContainer.Catalog.Dispose();
}
protected override void DisposeInUi()
{
base.DisposeInUi();
CompositionContainer.Dispose();
}
protected Uri GeneratePackUri(string relativePath)
{
string assemblyName = GetType().Assembly.GetName().Name;
string uri = string.Format("pack://application:,,,/{0};component/{1}", assemblyName, relativePath);
return new Uri(uri, UriKind.Absolute);
}
}
}