// Copyright (c) 2007-2016 CSJ2K contributors.
// Licensed under the BSD 3-Clause License.
namespace CSJ2K
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using CSJ2K.Util;
///
/// Setup helper methods for initializing library.
///
internal static class J2kSetup
{
///
/// Gets a single instance from the platform assembly implementing the type.
///
/// (Abstract) type for which implementation is requested.
/// The single instance from the platform assembly implementing the type,
/// or null if no or more than one implementations are available.
/// It is implicitly assumed that implementation class has a public, parameter-less constructor.
internal static T GetSinglePlatformInstance()
{
try
{
var assembly = GetCurrentAssembly();
#if NETFX_CORE || NETSTANDARD
var type =
assembly.DefinedTypes.Single(
t => (t.IsSubclassOf(typeof(T)) || typeof(T).GetTypeInfo().IsAssignableFrom(t)) && !t.IsAbstract)
.AsType();
#else
var type =
assembly.GetTypes()
.Single(t => (t.IsSubclassOf(typeof(T)) || typeof(T).IsAssignableFrom(t)) && !t.IsAbstract);
#endif
var instance = (T)Activator.CreateInstance(type);
return instance;
}
catch (Exception)
{
return default(T);
}
}
///
/// Gets the default classified instance from the platform assembly implementing the type.
///
/// (Abstract) type for which implementation is requested.
/// The single instance from the platform assembly implementing the type that is classified as default,
/// or null if no or more than one default classified implementations are available.
/// It is implicitly assumed that all implementation classes has a public, parameter-less constructor.
internal static T GetDefaultPlatformInstance() where T : IDefaultable
{
try
{
var assembly = GetCurrentAssembly();
var types = GetConcreteTypes(assembly);
return GetDefaultOrSingleInstance(types);
}
catch (Exception)
{
return default(T);
}
}
private static Assembly GetCurrentAssembly()
{
#if NETFX_CORE || NETSTANDARD
return typeof(J2kSetup).GetTypeInfo().Assembly;
#else
return typeof(J2kSetup).Assembly;
#endif
}
private static IEnumerable GetConcreteTypes(Assembly assembly)
{
#if NETFX_CORE || NETSTANDARD
return assembly.DefinedTypes.Where(
#else
return assembly.GetTypes().Where(
#endif
t =>
{
try
{
#if NETFX_CORE || NETSTANDARD
return (t.IsSubclassOf(typeof(T)) || typeof(T).GetTypeInfo().IsAssignableFrom(t))
&& !t.IsAbstract;
#else
return (t.IsSubclassOf(typeof(T)) || typeof(T).IsAssignableFrom(t)) && !t.IsAbstract;
#endif
}
catch
{
return false;
}
#if NETFX_CORE || NETSTANDARD
}).Select(t => t.AsType());
#else
});
#endif
}
private static T GetDefaultOrSingleInstance(IEnumerable types) where T : IDefaultable
{
var instances = types.Select(
t =>
{
try
{
return (T)Activator.CreateInstance(t);
}
catch
{
return default(T);
}
}).ToList();
return instances.Count > 1 ? instances.Single(instance => instance.IsDefault) : instances.SingleOrDefault();
}
}
}