Pool can now be used with types not derived from IRecyclable and/or without a public default constructor; consolidated type-related helper methods into a common helper class (TypeHelper.cs); optimized GetFieldInfosIncludingBaseClasses() method
git-svn-id: file:///srv/devel/repo-conversion/nusu@268 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
24439da822
commit
c91a082e84
18 changed files with 277 additions and 292 deletions
|
@ -36,7 +36,7 @@ namespace Nuclex.Support.Plugins {
|
|||
/// <param name="type">Type which will be assessed</param>
|
||||
/// <returns>True if the type can be employed, otherwise false</returns>
|
||||
public virtual bool CanEmploy(Type type) {
|
||||
return PluginHelper.HasDefaultConstructor(type);
|
||||
return type.HasDefaultConstructor();
|
||||
}
|
||||
|
||||
/// <summary>Employs the specified plugin type</summary>
|
||||
|
|
|
@ -24,7 +24,7 @@ using System.Collections.Generic;
|
|||
namespace Nuclex.Support.Plugins {
|
||||
|
||||
/// <summary>Employer to create factories of suiting types found in plugins</summary>
|
||||
/// <typeparam name="ProductType">
|
||||
/// <typeparam name="TProduct">
|
||||
/// Interface or base class that the types need to implement
|
||||
/// </typeparam>
|
||||
/// <remarks>
|
||||
|
@ -41,12 +41,12 @@ namespace Nuclex.Support.Plugins {
|
|||
/// a human-readable name, capabilities or an icon.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class FactoryEmployer<ProductType> : Employer where ProductType : class {
|
||||
public class FactoryEmployer<TProduct> : Employer where TProduct : class {
|
||||
|
||||
#region class ConcreteFactory
|
||||
|
||||
/// <summary>Concrete factory for the types in a plugin assembly</summary>
|
||||
private class ConcreteFactory : IAbstractFactory<ProductType>, IAbstractFactory {
|
||||
private class ConcreteFactory : IAbstractFactory<TProduct>, IAbstractFactory {
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a factory and configures it for the specified product
|
||||
|
@ -58,8 +58,8 @@ namespace Nuclex.Support.Plugins {
|
|||
|
||||
/// <summary>Create a new instance of the type the factory is configured to</summary>
|
||||
/// <returns>The newly created instance</returns>
|
||||
public ProductType CreateInstance() {
|
||||
return (ProductType)Activator.CreateInstance(this.concreteType);
|
||||
public TProduct CreateInstance() {
|
||||
return (TProduct)Activator.CreateInstance(this.concreteType);
|
||||
}
|
||||
|
||||
/// <summary>Create a new instance of the type the factory is configured to</summary>
|
||||
|
@ -77,11 +77,11 @@ namespace Nuclex.Support.Plugins {
|
|||
|
||||
/// <summary>Initializes a new FactoryEmployer</summary>
|
||||
public FactoryEmployer() {
|
||||
this.employedFactories = new List<IAbstractFactory<ProductType>>();
|
||||
this.employedFactories = new List<IAbstractFactory<TProduct>>();
|
||||
}
|
||||
|
||||
/// <summary>List of all factories that the instance employer has created</summary>
|
||||
public List<IAbstractFactory<ProductType>> Factories {
|
||||
public List<IAbstractFactory<TProduct>> Factories {
|
||||
get { return this.employedFactories; }
|
||||
}
|
||||
|
||||
|
@ -90,20 +90,20 @@ namespace Nuclex.Support.Plugins {
|
|||
/// <returns>True if the type can be employed</returns>
|
||||
public override bool CanEmploy(Type type) {
|
||||
return
|
||||
PluginHelper.HasDefaultConstructor(type) &&
|
||||
typeof(ProductType).IsAssignableFrom(type) &&
|
||||
type.HasDefaultConstructor() &&
|
||||
typeof(TProduct).IsAssignableFrom(type) &&
|
||||
!type.ContainsGenericParameters;
|
||||
}
|
||||
|
||||
/// <summary>Employs the specified plugin type</summary>
|
||||
/// <param name="type">Type to be employed</param>
|
||||
public override void Employ(Type type) {
|
||||
if(!PluginHelper.HasDefaultConstructor(type)) {
|
||||
if(!type.HasDefaultConstructor()) {
|
||||
throw new MissingMethodException(
|
||||
"Cannot employ type because it does not have a public default constructor"
|
||||
);
|
||||
}
|
||||
if(!typeof(ProductType).IsAssignableFrom(type)) {
|
||||
if(!typeof(TProduct).IsAssignableFrom(type)) {
|
||||
throw new InvalidCastException(
|
||||
"Cannot employ type because it cannot be cast to the factory's product type"
|
||||
);
|
||||
|
@ -118,7 +118,7 @@ namespace Nuclex.Support.Plugins {
|
|||
}
|
||||
|
||||
/// <summary>All factories that the instance employer has created</summary>
|
||||
private List<IAbstractFactory<ProductType>> employedFactories;
|
||||
private List<IAbstractFactory<TProduct>> employedFactories;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ using System.Collections.Generic;
|
|||
namespace Nuclex.Support.Plugins {
|
||||
|
||||
/// <summary>Employer that directly creates instances of the types in a plugin</summary>
|
||||
/// <typeparam name="T">Interface or base class required for the employed types</typeparam>
|
||||
/// <typeparam name="TEmployedType">Interface or base class required for the employed types</typeparam>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This employer directly creates an instance of any type in a plugin assembly that
|
||||
|
@ -44,15 +44,15 @@ namespace Nuclex.Support.Plugins {
|
|||
/// factory would then be implemented on the plugin side.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class InstanceEmployer<T> : Employer {
|
||||
public class InstanceEmployer<TEmployedType> : Employer {
|
||||
|
||||
/// <summary>Initializes a new instance employer</summary>
|
||||
public InstanceEmployer() {
|
||||
this.employedInstances = new List<T>();
|
||||
this.employedInstances = new List<TEmployedType>();
|
||||
}
|
||||
|
||||
/// <summary>All instances that have been employed</summary>
|
||||
public List<T> Instances {
|
||||
public List<TEmployedType> Instances {
|
||||
get { return this.employedInstances; }
|
||||
}
|
||||
|
||||
|
@ -61,19 +61,19 @@ namespace Nuclex.Support.Plugins {
|
|||
/// <returns>True if the type can be employed</returns>
|
||||
public override bool CanEmploy(Type type) {
|
||||
return
|
||||
PluginHelper.HasDefaultConstructor(type) &&
|
||||
typeof(T).IsAssignableFrom(type) &&
|
||||
type.HasDefaultConstructor() &&
|
||||
typeof(TEmployedType).IsAssignableFrom(type) &&
|
||||
!type.ContainsGenericParameters;
|
||||
}
|
||||
|
||||
/// <summary>Employs the specified plugin type</summary>
|
||||
/// <param name="type">Type to be employed</param>
|
||||
public override void Employ(Type type) {
|
||||
this.employedInstances.Add((T)Activator.CreateInstance(type));
|
||||
this.employedInstances.Add((TEmployedType)Activator.CreateInstance(type));
|
||||
}
|
||||
|
||||
/// <summary>All instances employed by the instance employer</summary>
|
||||
private List<T> employedInstances;
|
||||
private List<TEmployedType> employedInstances;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
#region CPL License
|
||||
/*
|
||||
Nuclex Framework
|
||||
Copyright (C) 2002-2012 Nuclex Development Labs
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the IBM Common Public License as
|
||||
published by the IBM Corporation; either version 1.0 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
IBM Common Public License for more details.
|
||||
|
||||
You should have received a copy of the IBM Common Public
|
||||
License along with this library
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
#if UNITTEST
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Nuclex.Support.Plugins {
|
||||
|
||||
/// <summary>Unit Test for the plugin helper class</summary>
|
||||
[TestFixture]
|
||||
internal class PluginHelperTest {
|
||||
|
||||
#region class NoDefaultConstructor
|
||||
|
||||
/// <summary>Test class that doesn't have a default constructor</summary>
|
||||
private class NoDefaultConstructor {
|
||||
/// <summary>Initializes a new instance of the test class</summary>
|
||||
/// <param name="dummy">Dummy argument so this is no default constructor</param>
|
||||
public NoDefaultConstructor(int dummy) { }
|
||||
}
|
||||
|
||||
#endregion // class NoDefaultConstructor
|
||||
|
||||
#region class NonPublicDefaultConstructor
|
||||
|
||||
/// <summary>Test class that has a non-public default constructor</summary>
|
||||
private class NonPublicDefaultConstructor {
|
||||
/// <summary>Initializes a new instance of the test class</summary>
|
||||
protected NonPublicDefaultConstructor() { }
|
||||
}
|
||||
|
||||
#endregion // class NonPublicDefaultConstructor
|
||||
|
||||
#region class PublicDefaultConstructor
|
||||
|
||||
/// <summary>Test class that has a public default constructor</summary>
|
||||
private class PublicDefaultConstructor {
|
||||
/// <summary>Initializes a new instance of the test class</summary>
|
||||
public PublicDefaultConstructor() { }
|
||||
}
|
||||
|
||||
#endregion // class PublicDefaultConstructor
|
||||
|
||||
/// <summary>Tests whether the default constructor detection works as expected</summary>
|
||||
[Test]
|
||||
public void TestDefaultConstructorDetection() {
|
||||
Assert.IsFalse(
|
||||
PluginHelper.HasDefaultConstructor(typeof(NoDefaultConstructor))
|
||||
);
|
||||
Assert.IsFalse(
|
||||
PluginHelper.HasDefaultConstructor(typeof(NonPublicDefaultConstructor))
|
||||
);
|
||||
Assert.IsTrue(
|
||||
PluginHelper.HasDefaultConstructor(typeof(PublicDefaultConstructor))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Support.Plugins
|
||||
|
||||
#endif // UNITTEST
|
|
@ -1,44 +0,0 @@
|
|||
#region CPL License
|
||||
/*
|
||||
Nuclex Framework
|
||||
Copyright (C) 2002-2012 Nuclex Development Labs
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the IBM Common Public License as
|
||||
published by the IBM Corporation; either version 1.0 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
IBM Common Public License for more details.
|
||||
|
||||
You should have received a copy of the IBM Common Public
|
||||
License along with this library
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Nuclex.Support.Plugins {
|
||||
|
||||
/// <summary>Supporting functions for the plugin classes</summary>
|
||||
public static class PluginHelper {
|
||||
|
||||
/// <summary>Determines whether the given type has a default constructor</summary>
|
||||
/// <param name="type">Type which is to be checked</param>
|
||||
/// <returns>True if the type has a default constructor</returns>
|
||||
public static bool HasDefaultConstructor(Type type) {
|
||||
ConstructorInfo[] constructors = type.GetConstructors();
|
||||
|
||||
foreach(ConstructorInfo constructor in constructors)
|
||||
if(constructor.IsPublic && (constructor.GetParameters().Length == 0))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Support.Plugins
|
|
@ -7,16 +7,16 @@ namespace Nuclex.Support.Plugins {
|
|||
#if !NO_CLONING
|
||||
|
||||
/// <summary>Factory that creates instances by cloning a prototype</summary>
|
||||
/// <typeparam name="ProductType">Type of product created by the factory</typeparam>
|
||||
/// <typeparam name="ConcreteType">Type of the prototype that will be cloned</typeparam>
|
||||
public class PrototypeFactory<ProductType, ConcreteType> :
|
||||
IAbstractFactory<ProductType>, IAbstractFactory, IDisposable
|
||||
where ProductType : class
|
||||
where ConcreteType : class, ICloneable {
|
||||
/// <typeparam name="TProduct">Type of product created by the factory</typeparam>
|
||||
/// <typeparam name="TConcreteType">Type of the prototype that will be cloned</typeparam>
|
||||
public class PrototypeFactory<TProduct, TConcreteType> :
|
||||
IAbstractFactory<TProduct>, IAbstractFactory, IDisposable
|
||||
where TProduct : class
|
||||
where TConcreteType : class, ICloneable {
|
||||
|
||||
/// <summary>Initializes a new prototype based factory</summary>
|
||||
/// <param name="prototype">Prototype instance that will be cloned</param>
|
||||
public PrototypeFactory(ConcreteType prototype) {
|
||||
public PrototypeFactory(TConcreteType prototype) {
|
||||
this.prototype = prototype;
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,8 @@ namespace Nuclex.Support.Plugins {
|
|||
/// Creates a new instance of the type to which the factory is specialized
|
||||
/// </summary>
|
||||
/// <returns>The newly created instance</returns>
|
||||
public ProductType CreateInstance() {
|
||||
return (ProductType)this.prototype.Clone();
|
||||
public TProduct CreateInstance() {
|
||||
return (TProduct)this.prototype.Clone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -49,7 +49,7 @@ namespace Nuclex.Support.Plugins {
|
|||
}
|
||||
|
||||
/// <summary>The prototype object</summary>
|
||||
private ConcreteType prototype;
|
||||
private TConcreteType prototype;
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue