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:
parent
4e2beb71b8
commit
c9d9810c28
21 changed files with 1516 additions and 48 deletions
141
Source/Plugins/PrototypeFactory.Test.cs
Normal file
141
Source/Plugins/PrototypeFactory.Test.cs
Normal 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
|
||||
54
Source/Plugins/PrototypeFactory.cs
Normal file
54
Source/Plugins/PrototypeFactory.cs
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue