Nailed the unit test coverage for all classes in the root namespace at 100%; fixed ugly german comment in ReadOnlyDictionary; moved AbstractFactory interface for FactoryEmployer in Nuclex.Support.Plugins into its own file; wrote unit tests for the PluginHelper, Shared, StringSegment and WeakReference classes

git-svn-id: file:///srv/devel/repo-conversion/nusu@93 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2008-11-26 19:15:36 +00:00
parent ddff1d8353
commit cb0355193d
16 changed files with 738 additions and 46 deletions

View file

@ -0,0 +1,39 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2008 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.Collections.Generic;
namespace Nuclex.Support.Plugins {
/// <summary>Abstract factory for a concrete type</summary>
/// <typeparam name="ProductType">Interface or base class of the product of the factory</typeparam>
public interface IAbstractFactory<ProductType> {
/// <summary>The concrete type as implemented by the factory instance</summary>
Type ConcreteType { get; }
/// <summary>Creates a new instance of the type to which the factory is specialized</summary>
/// <returns>The newly created instance</returns>
ProductType CreateInstance();
}
} // namespace Nuclex.Support.Plugins

View file

@ -34,7 +34,7 @@ namespace Nuclex.Support.Plugins {
/// <summary>Determines whether the type suites the employer's requirements</summary>
/// <param name="type">Type which will be assessed</param>
/// <returns>True if the type can be employed</returns>
/// <returns>True if the type can be employed, otherwise false</returns>
public virtual bool CanEmploy(Type type) {
return PluginHelper.HasDefaultConstructor(type);
}

View file

@ -23,21 +23,10 @@ using System.Collections.Generic;
namespace Nuclex.Support.Plugins {
/// <summary>Abstract factory</summary>
/// <typeparam name="T">Interface or base class of the product of the factory</typeparam>
public interface IFactory<T> {
/// <summary>The concrete type as implemented by the factory instance</summary>
Type ConcreteType { get; }
/// <summary>Creates a new instance of the type to which the factory is specialized</summary>
/// <returns>The newly created instance</returns>
T CreateInstance();
}
/// <summary>Employer to create factories of suiting types found in plugins</summary>
/// <typeparam name="T">Interface or base class that the types need to implement</typeparam>
/// <typeparam name="ProductType">
/// Interface or base class that the types need to implement
/// </typeparam>
/// <remarks>
/// <para>
/// This employer will not directly instanciate any compatible types found in
@ -52,16 +41,16 @@ namespace Nuclex.Support.Plugins {
/// a human-readable name, capabilities or an icon.
/// </para>
/// </remarks>
public class FactoryEmployer<T> : Employer {
public class FactoryEmployer<ProductType> : Employer {
#region class Factory
#region class ConcreteFactory
/// <summary>Concrete factory for the types in a plugin assembly</summary>
private class Factory : IFactory<T> {
private class ConcreteFactory : IAbstractFactory<ProductType> {
/// <summary>Initializes a factory and configures it for the specified product</summary>
/// <param name="type">Type of which the factory creates instances</param>
public Factory(Type type) {
public ConcreteFactory(Type type) {
this.concreteType = type;
}
@ -72,8 +61,8 @@ namespace Nuclex.Support.Plugins {
/// <summary>Create a new instance of the type that the factory is configured to</summary>
/// <returns>The newly created instance</returns>
public T CreateInstance() {
return (T)Activator.CreateInstance(this.concreteType);
public ProductType CreateInstance() {
return (ProductType)Activator.CreateInstance(this.concreteType);
}
/// <summary>Concrete product which the factory instance creates</summary>
@ -85,11 +74,11 @@ namespace Nuclex.Support.Plugins {
/// <summary>Initializes a new FactoryEmployer</summary>
public FactoryEmployer() {
this.employedFactories = new List<IFactory<T>>();
this.employedFactories = new List<IAbstractFactory<ProductType>>();
}
/// <summary>List of all factories that the instance employer has created</summary>
public List<IFactory<T>> Factories {
public List<IAbstractFactory<ProductType>> Factories {
get { return this.employedFactories; }
}
@ -99,17 +88,17 @@ namespace Nuclex.Support.Plugins {
public override bool CanEmploy(Type type) {
return
PluginHelper.HasDefaultConstructor(type) &&
typeof(T).IsAssignableFrom(type);
typeof(ProductType).IsAssignableFrom(type);
}
/// <summary>Employs the specified plugin type</summary>
/// <param name="type">Type to be employed</param>
public override void Employ(Type type) {
this.employedFactories.Add(new Factory(type));
this.employedFactories.Add(new ConcreteFactory(type));
}
/// <summary>All factories that the instance employer has created</summary>
private List<IFactory<T>> employedFactories;
private List<IAbstractFactory<ProductType>> employedFactories;
}

View file

@ -0,0 +1,84 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2008 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;
using NUnit.Framework.SyntaxHelpers;
namespace Nuclex.Support.Plugins {
/// <summary>Unit Test for the plugin helper class</summary>
[TestFixture]
public 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

View file

@ -19,20 +19,21 @@ License along with this library
#endregion
using System;
using System.Reflection;
namespace Nuclex.Support.Plugins {
/// <summary>Supporting functions for the plugin classes</summary>
internal static class PluginHelper {
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) {
System.Reflection.ConstructorInfo[] constructors = type.GetConstructors();
ConstructorInfo[] constructors = type.GetConstructors();
foreach(System.Reflection.ConstructorInfo constructor in constructors)
if(constructor.IsPublic && (constructor.GetParameters().Length != 0))
foreach(ConstructorInfo constructor in constructors)
if(constructor.IsPublic && (constructor.GetParameters().Length == 0))
return true;
return false;