Added prototype factory - a factory which created instances by cloning a prototype instance; redesigned the service manager to query types from an ITypeLister interface instead of tightly coupling it with the PluginRepository class; added type listers that list all assemblies in an app domain, in a PluginRepository and in a predefined list; renamed the IProgressTrackingService to IProgressCollectingService to make it perfectly clear which service is for which purpose; added Instancing.None to disallow the service manager from providing a certain contract; added CPL headers where they were missing

git-svn-id: file:///srv/devel/repo-conversion/nusu@140 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2009-05-27 19:55:06 +00:00
parent 4e2beb71b8
commit c9d9810c28
21 changed files with 1516 additions and 48 deletions

View file

@ -0,0 +1,141 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2009 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
#if UNITTEST
using System;
using System.IO;
using NUnit.Framework;
namespace Nuclex.Support.Plugins {
/// <summary>Unit Test for the prototype-based factory class</summary>
[TestFixture]
public class PrototypeFactoryTest {
#region interface IProduct
/// <summary>Interface used for the product in the unit test</summary>
private interface IProduct {
/// <summary>Some value associated with the product</summary>
int Value { get; }
}
#endregion // interface IProduct
#region class ConcretePrototype
/// <summary>
/// Class derived from the abstract base to serve as concrete product for
/// testing the factory employer
/// </summary>
private class ConcretePrototype : IProduct, ICloneable, IDisposable {
/// <summary>Initializes a new instance of the prototype product</summary>
/// <param name="value">Value that will be associated with this instance</param>
public ConcretePrototype(int value) {
this.value = value;
}
/// <summary>Immediately releases all resources owned by the instance</summary>
public void Dispose() {
this.disposed = true;
}
/// <summary>Value the product has been associated with</summary>
public int Value { get { return this.value; } }
/// <summary>Whether the prototype instance has been disposed</summary>
public bool IsDisposed {
get { return this.disposed; }
}
/// <summary>Creates an identical copy of the instance</summary>
/// <returns>An identical copy of the instance</returns>
object ICloneable.Clone() {
return new ConcretePrototype(this.value);
}
/// <summary>Value associated with the product</summary>
private int value;
/// <summary>Whether the instance has been disposed</summary>
private bool disposed;
}
#endregion // class ConcretePrototype
/// <summary>
/// Tests whether the prototype-based factory behaves correctly by creating
/// new instances of its product using clones of its assigned prototype.
/// </summary>
[Test]
public void TestGenericInstanceCreation() {
ConcretePrototype template = new ConcretePrototype(42);
IAbstractFactory<IProduct> factory = new PrototypeFactory<
IProduct, ConcretePrototype
>(template);
IProduct factoryCreatedProduct = factory.CreateInstance();
Assert.AreEqual(template.Value, factoryCreatedProduct.Value);
}
/// <summary>
/// Tests whether the prototype-based factory behaves correctly by creating
/// new instances of its product using clones of its assigned prototype.
/// </summary>
[Test]
public void TestInstanceCreation() {
ConcretePrototype template = new ConcretePrototype(42);
IAbstractFactory factory = new PrototypeFactory<
IProduct, ConcretePrototype
>(template);
IProduct factoryCreatedProduct = (IProduct)factory.CreateInstance();
Assert.AreEqual(template.Value, factoryCreatedProduct.Value);
}
/// <summary>
/// Tests whether the prototype is disposed if it implements the IDisposable
/// interface and the factory is explicitely disposed.
/// </summary>
[Test]
public void TestPrototypeDisposal() {
ConcretePrototype template = new ConcretePrototype(42);
PrototypeFactory<IProduct, ConcretePrototype> factory = new PrototypeFactory<
IProduct, ConcretePrototype
>(template);
Assert.IsFalse(template.IsDisposed);
factory.Dispose();
Assert.IsTrue(template.IsDisposed);
}
}
} // namespace Nuclex.Support.Plugins
#endif // UNITTEST

View file

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Nuclex.Support.Plugins {
/// <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 {
/// <summary>Initializes a new prototype based factory</summary>
/// <param name="prototype">Prototype instance that will be cloned</param>
public PrototypeFactory(ConcreteType prototype) {
this.prototype = prototype;
}
/// <summary>
/// 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();
}
/// <summary>
/// Creates a new instance of the type to which the factory is specialized
/// </summary>
/// <returns>The newly created instance</returns>
object IAbstractFactory.CreateInstance() {
return this.prototype.Clone();
}
/// <summary>Immediately releases all resources owned by the instance</summary>
public void Dispose() {
if(this.prototype != null) {
IDisposable disposablePrototype = this.prototype as IDisposable;
if(disposablePrototype != null) {
disposablePrototype.Dispose();
}
this.prototype = null;
}
}
/// <summary>The prototype object</summary>
private ConcreteType prototype;
}
} // namespace Nuclex.Support.Plugins