Moves services directory into Nuclex.Support.Plugins project

git-svn-id: file:///srv/devel/repo-conversion/nusu@276 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2012-03-11 09:05:15 +00:00
parent c9b20cd2cd
commit 92733d147b
18 changed files with 0 additions and 1833 deletions

View File

@ -1,77 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Unit Test for the cached app domain type lister</summary>
[TestFixture]
public class AppDomainTypeListerTest {
/// <summary>
/// Verifies that the assembly type list is generated correctly for
/// the default constructor (using the calling app domain)
/// </summary>
[Test]
public void TestDefaultConstructur() {
AppDomainTypeLister testLister = new AppDomainTypeLister();
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(AppDomainTypeListerTest)).And.Member(typeof(Assembly))
);
}
/// <summary>
/// Verifies that the assembly type list is generated correctly for
/// the full constructor
/// </summary>
[Test]
public void TestFullConstructur() {
AppDomain newAppDomain = AppDomain.CreateDomain("AppDomainTypeListerTest.Domain");
try {
AppDomainTypeLister testLister = new AppDomainTypeLister(newAppDomain);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(Assembly)).And.No.Member(typeof(AppDomainTypeListerTest))
);
}
finally {
AppDomain.Unload(newAppDomain);
}
}
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER
#endif // UNITTEST

View File

@ -1,63 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Reflection;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
#if WINDOWS
/// <summary>Lists the types of all assemblies in an application domain</summary>
public class AppDomainTypeLister : MultiAssemblyTypeLister {
/// <summary>
/// Initializes a new application domain type lister using the application domain
/// of the calling method
/// </summary>
public AppDomainTypeLister() : this(AppDomain.CurrentDomain) { }
/// <summary>Initializes a new application domain type lister</summary>
/// <param name="appDomain">Application domain whose types will be listed</param>
public AppDomainTypeLister(AppDomain appDomain) {
this.appDomain = appDomain;
}
/// <summary>
/// Obtains an enumerable list of all assemblies in the application domain
/// </summary>
/// <returns>An enumerable list of the assemblies in the application domain</returns>
protected override IEnumerable<Assembly> GetAssemblies() {
return this.appDomain.GetAssemblies();
}
/// <summary>Application domain whose types the lister works on</summary>
private AppDomain appDomain;
}
#endif // WINDOWS
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,107 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Unit Test for the predefined type lister</summary>
[TestFixture]
public class ExplicitTypeListerTest {
/// <summary>
/// Verifies that the type lister correctly takes over a list of types
/// supplied manually to the constructor
/// </summary>
[Test]
public void TestPredefinedTypesFromParams() {
ITypeLister testLister = new ExplicitTypeLister(
typeof(ExplicitTypeListerTest), typeof(TestAttribute)
);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(ExplicitTypeListerTest)).And.Member(typeof(TestAttribute))
);
}
/// <summary>
/// Verifies that the type lister correctly takes over a list of types
/// supplied as an enumerable list to the constructor
/// </summary>
[Test]
public void TestPredefinedTypesFromEnumerable() {
IEnumerable<Type> types = typeof(ExplicitTypeListerTest).Assembly.GetTypes();
ITypeLister testLister = new ExplicitTypeLister(types);
Assert.That(
testLister.GetTypes(), Has.Member(typeof(ExplicitTypeListerTest))
);
}
/// <summary>
/// Verifies that types can be removed from the type lister
/// </summary>
[Test]
public void TestRemoveTypesFromLister() {
ExplicitTypeLister testLister = new ExplicitTypeLister(
typeof(ExplicitTypeListerTest).Assembly.GetTypes()
);
Assert.That(
testLister.GetTypes(), Has.Member(typeof(ExplicitTypeListerTest))
);
testLister.Types.Remove(typeof(ExplicitTypeListerTest));
Assert.That(
testLister.GetTypes(), Has.No.Member(typeof(ExplicitTypeListerTest))
);
}
/// <summary>
/// Verifies that types can be added to the type lister
/// </summary>
[Test]
public void TestAddTypesToLister() {
ExplicitTypeLister testLister = new ExplicitTypeLister();
Assert.That(
testLister.GetTypes(), Has.No.Member(typeof(TestAttribute))
);
testLister.Types.Add(typeof(TestAttribute));
Assert.That(
testLister.GetTypes(), Has.Member(typeof(TestAttribute))
);
}
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER
#endif // UNITTEST

View File

@ -1,64 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Text;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Type lister that returns a predefined list of types</summary>
public class ExplicitTypeLister : ITypeLister {
/// <summary>Initializes a new predefined type lister</summary>
/// <param name="types">Types the predefined type lister will list</param>
public ExplicitTypeLister(params Type[] types) {
this.types = new List<Type>(types);
}
/// <summary>Initializes a new predefined type lister</summary>
/// <param name="types">Types the predefined type lister will list</param>
public ExplicitTypeLister(IEnumerable<Type> types) {
this.types = new List<Type>(types);
}
/// <summary>
/// Returns an enumerable list of types that will be checked by the service manager
/// </summary>
/// <returns>An enumerable list of types for the service manager</returns>
public IEnumerable<Type> GetTypes() {
return this.types;
}
/// <summary>Predefined list of types the lister will list</summary>
public List<Type> Types {
get { return this.types; }
}
/// <summary>The predefined list of types</summary>
private List<Type> types;
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,46 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Reflection;
using Nuclex.Support.Plugins;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>
/// Provides a type list the service manager uses to locate components
/// </summary>
public interface ITypeLister {
/// <summary>
/// Returns an enumerable list of types that will be checked by the service manager
/// </summary>
/// <returns>An enumerable list of types for the service manager</returns>
IEnumerable<Type> GetTypes();
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,49 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using Nuclex.Support.Plugins;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Modes in which services can be instantiated</summary>
public enum Instancing {
/// <summary>Disallow any service from being created for a contract</summary>
Never,
/// <summary>There will only be one service in the whole process</summary>
Singleton,
/// <summary>Each thread will be assigned its own service</summary>
InstancePerThread,
/// <summary>A new service will be created each time it is queried for</summary>
Factory
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,143 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Unit Test for the cached assembly type lister</summary>
[TestFixture]
public class MultiAssemblyTypeListerTest {
#region class TestAssemblyTypeLister
/// <summary>Test implementation of a cached assembly type lister</summary>
private class TestAssemblyTypeLister : MultiAssemblyTypeLister {
/// <summary>Initializes a new test assembly type lister</summary>
/// <param name="assemblies">Assemblies whose types will be listed</param>
public TestAssemblyTypeLister(params Assembly[] assemblies) {
ReplaceAssemblyList(assemblies);
}
/// <summary>Replaces the list of assemblies whose types to list</summary>
/// <param name="assemblies">Assemblies whose types will be listed</param>
public void ReplaceAssemblyList(params Assembly[] assemblies) {
this.assemblies = assemblies;
}
/// <summary>Obtains a list of any assemblies whose types should be listed</summary>
/// <returns>A list of any assemblies whose types to list</returns>
protected override IEnumerable<Assembly> GetAssemblies() {
return this.assemblies;
}
/// <summary>Assemblies whose types the test assembly type lister lists</summary>
private Assembly[] assemblies;
}
#endregion // class TestAssemblyTypeLister
/// <summary>
/// Verifies that the assembly type list is generated correctly
/// </summary>
[Test]
public void TestAssemblyListGeneration() {
TestAssemblyTypeLister testLister = new TestAssemblyTypeLister(
typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(), Has.Member(typeof(MultiAssemblyTypeListerTest))
);
}
/// <summary>
/// Verifies that the assembly type list is updated when list of assemblies
/// changes inbetween calls
/// </summary>
[Test]
public void TestAssemblyListReplacement() {
TestAssemblyTypeLister testLister = new TestAssemblyTypeLister(
typeof(Assembly).Assembly,
typeof(TestAttribute).Assembly
);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(TestAttribute)).And.Not.Member(typeof(MultiAssemblyTypeListerTest))
);
testLister.ReplaceAssemblyList(
typeof(Assembly).Assembly,
typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(MultiAssemblyTypeListerTest)).And.Not.Member(typeof(TestAttribute))
);
}
/// <summary>
/// Verifies that the assembly type list is updated when an assembly is removed
/// from the list inbetween calls
/// </summary>
[Test]
public void TestAssemblyListRemoval() {
TestAssemblyTypeLister testLister = new TestAssemblyTypeLister(
typeof(Assembly).Assembly,
typeof(TestAttribute).Assembly,
typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(TestAttribute)).And.Member(typeof(MultiAssemblyTypeListerTest))
);
testLister.ReplaceAssemblyList(
typeof(Assembly).Assembly,
typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(MultiAssemblyTypeListerTest)).And.Not.Member(typeof(TestAttribute))
);
}
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER
#endif // UNITTEST

View File

@ -1,166 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Reflection;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Lists all types in a changing set of assemblies</summary>
public abstract class MultiAssemblyTypeLister : ITypeLister {
#region class AssemblyTypes
/// <summary>Caches the list of types types for an assembly</summary>
private class AssemblyTypes {
/// <summary>Initializes a new cached assembly types list</summary>
/// <param name="assembly">Assembly the types are found in</param>
/// <param name="types">Types defined in the assembly</param>
public AssemblyTypes(Assembly assembly, Type[] types) {
this.Assembly = assembly;
this.Types = types;
}
/// <summary>Assembly the types are found in</summary>
public Assembly Assembly;
/// <summary>Types defined in the assembly</summary>
public Type[] Types;
}
#endregion // class AssemblyTypes
/// <summary>Initializes a new assembly type lister</summary>
public MultiAssemblyTypeLister() {
this.assemblyTypes = new LinkedList<AssemblyTypes>();
}
/// <summary>Enumerates all types in the lister's assembly set</summary>
/// <returns>An enumerator over all types in the lister's assembly set</returns>
public IEnumerable<Type> GetTypes() {
// Make sure the assembly list is filled and up-to-date
if(this.assemblyTypes.Count == 0) {
enlistAssembliesFirstTime();
} else {
updateAssemblyList();
}
// Iterate over all types in all assemblies
LinkedListNode<AssemblyTypes> node = this.assemblyTypes.First;
while(node != null) {
Type[] types = node.Value.Types;
for(int index = 0; index < types.Length; ++index) {
yield return types[index];
}
node = node.Next;
}
}
/// <summary>Called when the assemblies set is queried for the first time</summary>
private void enlistAssembliesFirstTime() {
foreach(Assembly assembly in GetAssemblies()) {
this.assemblyTypes.AddLast(new AssemblyTypes(assembly, assembly.GetTypes()));
}
}
/// <summary>Called to update the assembly list if it has changed</summary>
private void updateAssemblyList() {
LinkedListNode<AssemblyTypes> node = this.assemblyTypes.First;
foreach(Assembly assembly in GetAssemblies()) {
// If we reached the end of the cache, this automatically becomes a new entry
if(node == null) {
this.assemblyTypes.AddLast(new AssemblyTypes(assembly, assembly.GetTypes()));
} else { // Otherwise, figure out whether the assembly list has changed
// Try to locate the cached entry for this assembly. If we have to skip entries,
// we know that an assembly might have been removed from the set. This will be
// handled by moved all matched assemblies to the beginning, so that when we
// finish, the assemblies after the last checked one automatically become those
// which are no longer in the set.
LinkedListNode<AssemblyTypes> existingNode = node;
while(existingNode.Value.Assembly != assembly) {
existingNode = existingNode.Next;
if(existingNode == null) {
break;
}
}
// Is this assembly not yet in the cache?
if(existingNode == null) {
// If this assembly wasn't found in the cache, add it in the same order
// it was returned by the enumerator. This will improve efficiency later
// since the update algorithm is designed to perform optimally if the order
// remains the same between calls.
this.assemblyTypes.AddBefore(
node, new AssemblyTypes(assembly, assembly.GetTypes())
);
} else if(existingNode != node) { // Did we skip other cached assemblies?
// If other cached assemblies had to be skipped, this indicates that
// the set of assemblies has changed. Move the list nodes to the same order
// in which the assemblies are returned by the enumerator. Any cached
// assemblies that have been completely removed from the set will therefore
// end up at the bottom of the list after the update has completed.
this.assemblyTypes.Remove(existingNode);
this.assemblyTypes.AddBefore(node, existingNode);
} else { // Assembly was found in the expected place
// If the assembly was found in the same place as it was found during
// the last check, the assembly list is unchanged at this entry.
node = node.Next;
}
}
}
// Any nodes behind the last checked node contain cached type lists for assemblies
// that are no longer in the set, so these will be removed.
while(node != null) {
LinkedListNode<AssemblyTypes> nextNode = node.Next;
this.assemblyTypes.Remove(node);
node = nextNode;
}
}
/// <summary>Obtains a list of any assemblies whose types should be listed</summary>
/// <returns>A list of any assemblies whose types to list</returns>
protected abstract IEnumerable<Assembly> GetAssemblies();
/// <summary>Cached assembly type lists</summary>
private LinkedList<AssemblyTypes> assemblyTypes;
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,92 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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 ENABLE_SERVICEMANAGER
using System;
using System.Collections.Generic;
using Nuclex.Support.Tracking;
namespace Nuclex.Support.Services.ProgressTracking {
/// <summary>Allows application-wide tracking of progress</summary>
interface IProgressCollectingService {
/// <summary>Tracks the progress of the specified transaction</summary>
/// <param name="transaction">
/// Transaction whose progress will be tracked
/// </param>
/// <param name="processIdentifier">
/// Identifier unique to the tracked background process. Can be null.
/// </param>
/// <remarks>
/// <para>
/// Using the process identifier allows you to track the progress of multiple
/// transactions that are working independently of each other. This could,
/// for example, result in multiple progress bars being displayed in a GUI.
/// The global progress always is a combination of all transactions tracked
/// by the service.
/// </para>
/// <para>
/// A good analogy for this might be a download manager which uses several
/// threads to download multiple sections of a file at the same time. You
/// want a progress bar per file, but not one for each downloading thread.
/// Specifying the name object as a process identifer, all transactions
/// belonging to the same file would be merged into a single progress source.
/// </para>
/// <para>
/// The process identifier can be a string or any object. Note however that
/// as common practice, this object's ToString() method should return
/// something reasonable, like "Downloading xy.txt". Localization can be
/// achieved by implementing an interface (eg. ILocalizableToString) which
/// provides a string and some parameters - or you could return the already
/// translated versions of the string if you prefer to have localized versions
/// of internal assemblies.
/// </para>
/// </remarks>
void Track(Transaction transaction, object processIdentifier);
/// <summary>Tracks the progress of the specified transaction</summary>
/// <param name="transaction">
/// Transaction whose progress will be tracked
/// </param>
/// <remarks>
/// Tracks the transaction as if it was added with the process identifier
/// set to null.
/// </remarks>
void Track(Transaction transaction);
/// <summary>Stops tracking the specified transaction</summary>
/// <param name="transaction">Transaction that will no longer be tracked</param>
/// <remarks>
/// Untracking a transaction is optional. The service will automatically
/// remove finished transactions from its list of tracked transactions. Calling
/// this method is only required if you drop a transaction in a way that
/// prevents its AsyncEnded event from being fired (eg. by not executing it
/// at all, dispite adding it to the progress tracking service).
/// </remarks>
void Untrack(Transaction transaction);
}
} // namespace Nuclex.Support.DependencyInjection.ProgressTracking
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,58 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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 ENABLE_SERVICEMANAGER
using System;
using System.Collections.Generic;
using Nuclex.Support.Tracking;
namespace Nuclex.Support.Services.ProgressTracking {
/// <summary>Reports the progress of tracked background processes</summary>
/// <remarks>
/// <para>
/// This service is intended for the consumer of progress reports. It will notify
/// subscribers when background processes start, when progress is achieved and
/// when they finish.
/// </para>
/// <para>
/// Usually, this interface, together with the IProgressTrackingService interface,
/// is provided by a single service component that tracks the progress of
/// transactions taking place asynchronously and reports it back this way.
/// </para>
/// </remarks>
interface IProgressPublishingService {
/// <summary>Fired when the overall progress changes</summary>
event EventHandler<ProgressReportEventArgs> ProgressChanged;
/// <summary>The overall progress of all tracked background processes</summary>
float TotalProgress { get; }
/// <summary>Currently active background processes</summary>
IEnumerable<ITrackedProcess> TrackedProcesses { get; }
}
} // namespace Nuclex.Support.DependencyInjection.ProgressTracking
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,53 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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 ENABLE_SERVICEMANAGER
using System;
using System.Collections.Generic;
using Nuclex.Support.Tracking;
namespace Nuclex.Support.Services.ProgressTracking {
/// <summary>Process whose progress is being tracked</summary>
public interface ITrackedProcess {
/// <summary>Fired whenever the progress of the process changes</summary>
event EventHandler<ProgressReportEventArgs> ProgressChanged;
/// <summary>Unique identifier of the overall process</summary>
/// <remarks>
/// As a convention, using this object's ToString() method should return
/// something usable, either a string that can be displayed in the user
/// interface or, depending on your architecture, the object could
/// implement certain interfaces that allow a localized version of
/// the string to be created.
/// </remarks>
object ProcessIdentifier { get; }
/// <summary>Progress that process has achieved so far</summary>
float CurrentProgress { get; }
}
} // namespace Nuclex.Support.DependencyInjection.ProgressTracking
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,78 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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 ENABLE_SERVICEMANAGER
using System;
using System.Collections.Generic;
using Nuclex.Support.Tracking;
namespace Nuclex.Support.Services.ProgressTracking {
/// <summary>Tracks the progress of running background processes</summary>
public class ProgressTrackingComponent :
IProgressCollectingService,
IProgressPublishingService {
/// <summary>Fired when the overall progress changes</summary>
public event EventHandler<ProgressReportEventArgs> ProgressChanged;
/// <summary>Initializes a new progress tracking component</summary>
public ProgressTrackingComponent() {
}
/// <summary>Tracks the progress of the specified transaction</summary>
/// <param name="transaction">
/// Transaction whose progress will be tracked
/// </param>
/// <param name="processIdentifier">
/// Identifier unique to the tracked background process. Can be null.
/// </param>
public void Track(Transaction transaction, object processIdentifier) {
}
/// <summary>Tracks the progress of the specified transaction</summary>
/// <param name="transaction">
/// Transaction whose progress will be tracked
/// </param>
public void Track(Transaction transaction) {
}
/// <summary>Stops tracking the specified transaction</summary>
/// <param name="transaction">Transaction that will no longer be tracked</param>
public void Untrack(Transaction transaction) {
}
/// <summary>The overall progress of all tracked background processes</summary>
public float TotalProgress {
get { return 0.0f; }
}
/// <summary>Currently active background processes</summary>
public IEnumerable<ITrackedProcess> TrackedProcesses {
get { return null; }
}
}
} // namespace Nuclex.Support.Services.ProgressTracking
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,67 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Unit Test for the cached assembly repository type lister</summary>
[TestFixture]
public class RepositoryTypeListerTest {
/// <summary>
/// Tests whether the repository lister can cope with an empty repository
/// </summary>
[Test]
public void TestEmptyLister() {
RepositoryTypeLister testLister = new RepositoryTypeLister();
Assert.That(testLister.GetTypes(), Is.Empty);
}
/// <summary>
/// Tests whether the repository lister notices an updated repository
/// </summary>
[Test]
public void TestLateAdd() {
RepositoryTypeLister testLister = new RepositoryTypeLister();
testLister.Repository.AddAssembly(typeof(RepositoryTypeListerTest).Assembly);
Assert.That(
testLister.GetTypes(),
Has.Member(typeof(RepositoryTypeListerTest))
);
}
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER
#endif // UNITTEST

View File

@ -1,76 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Reflection;
using Nuclex.Support.Plugins;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>
/// Lists the types of all assemblies contained in an assembly repository
/// </summary>
public class RepositoryTypeLister : MultiAssemblyTypeLister {
/// <summary>
/// Initializes a new repository type lister using a new repository
/// </summary>
public RepositoryTypeLister() : this(new PluginRepository()) { }
/// <summary>
/// Initializes a new repository type lister using an existing repository
/// </summary>
/// <param name="repository">
/// Repository containing the assemblies whose types will be listed
/// </param>
public RepositoryTypeLister(PluginRepository repository) {
this.repository = repository;
}
/// <summary>
/// Returns an enumerable list of the assemblies in the repository
/// </summary>
/// <returns>An enumerable list of the assemblies in the repository</returns>
protected override IEnumerable<Assembly> GetAssemblies() {
return this.repository.LoadedAssemblies;
}
/// <summary>
/// The assembly repository containing the assemblies whose types the lister
/// operates on.
/// </summary>
public PluginRepository Repository {
get { return this.repository; }
}
/// <summary>
/// Repository containing the assemblies with the type lister's types
/// </summary>
private PluginRepository repository;
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,53 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Reflection;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
partial class ServiceManager {
#region class Analyzer
/// <summary>Analyzes Component dependencies</summary>
private static class Analyzer {
public static KeyValuePair<string, Type>[] GetRequirements(ConstructorInfo constructor) {
ParameterInfo[] parameters = constructor.GetParameters();
//parameters[0].IsOptional
return null;
}
}
#endregion // class Analyzer
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,116 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Text;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
partial class ServiceManager {
#region class ForContext
/// <summary>Manages the context of the "For" modifier</summary>
public class ForContext {
/// <summary>Initializes a new "For" context of the service manager</summary>
/// <param name="serviceManager">Service manager the context operates on</param>
/// <param name="contractType">Contract that is being modified</param>
internal ForContext(ServiceManager serviceManager, Type contractType) {
this.serviceManager = serviceManager;
this.contractType = contractType;
}
/// <summary>Uses the specified implementation for the contract</summary>
/// <param name="contractImplementation">
/// Implementation that will be used for the contract
/// </param>
public void Use(object contractImplementation) { }
/// <summary>
/// Uses the provided object as a prototype for the contract implementation
/// </summary>
/// <param name="contractImplementationPrototype">
/// Contract implementation that will be used as a prototype
/// </param>
public void UsePrototype(object contractImplementationPrototype) { }
/// <summary>Selects the default implementation to use for the contract</summary>
/// <param name="implementationType">
/// Implementation that will be used as the default for the contract
/// </param>
public void UseDefault(Type implementationType) { }
/// <summary>Service manager the "For" context operates on</summary>
protected ServiceManager serviceManager;
/// <summary>Contract that is being modified</summary>
protected Type contractType;
}
#endregion // class ForContext
#region class ForContext<>
/// <summary>Manages the context of the "For" modifier</summary>
public class ForContext<ContractType> : ForContext {
/// <summary>Initializes a new "For" context of the service manager</summary>
/// <param name="serviceManager">Service manager the context operates on</param>
internal ForContext(ServiceManager serviceManager) :
base(serviceManager, typeof(ContractType)) { }
/// <summary>Uses the specified implementation for the contract</summary>
/// <param name="implementation">
/// Implementation that will be used for the contract
/// </param>
public void Use(ContractType implementation) { }
/// <summary>
/// Uses the provided object as a prototype for the contract implementation
/// </summary>
/// <typeparam name="PrototypeType">
/// Type of the implementation that will be used as a prototype
/// </typeparam>
/// <param name="contractImplementationPrototype">
/// Contract implementation that will be used as a prototype
/// </param>
public void UsePrototype<PrototypeType>(PrototypeType contractImplementationPrototype)
where PrototypeType : ContractType, ICloneable { }
/// <summary>Selects the default implementation to use for the contract</summary>
/// <typeparam name="ImplementationType">
/// Implementation that will be used as the default for the contract
/// </typeparam>
public void UseDefault<ImplementationType>()
where ImplementationType : ContractType { }
}
#endregion // class ForContext<>
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER

View File

@ -1,199 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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 Nuclex.Support.Plugins;
using NUnit.Framework;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
/// <summary>Unit Test for the service manager class</summary>
[TestFixture]
public class ServiceManagerTest {
#region interface IHelloContract
/// <summary>A simple contract interface used for testing</summary>
public interface IHelloContract { }
#endregion // interface IHelloContract
#region interface IWorldContract
/// <summary>Another simple contract interface used for testing</summary>
public interface IWorldContract { }
#endregion // interface IWorldContract
#region interface IHaveNoImplementation
/// <summary>A contract interface that is not implementated anywhere</summary>
public interface IHaveNoImplementation { }
#endregion // interface IHaveNoImplementation
#region class HelloComponent
/// <summary>Test component that implements the hello contract</summary>
public class HelloComponent : IHelloContract { }
#endregion // class HelloComponent
#region class WorldComponent
/// <summary>
/// Test component that implements the world contract and requires
/// an implementation of the hello contract
/// </summary>
public class WorldComponent : IWorldContract, IHelloContract {
/// <summary>Initializes a new world component</summary>
/// <param name="helloContracts">
/// Array of hello contract implementations that will be used
/// </param>
public WorldComponent(IHelloContract[] helloContracts) { }
}
#endregion // class WorldComponent
#region class IncompleteComponent
/// <summary>
/// Test component that requires an implementation of a contract that has
/// no implementation available
/// </summary>
public class IncompleteComponent : IWorldContract {
/// <summary>Initializes the component</summary>
/// <param name="noImplementation">
/// Implementation of the unimplemented interface (:P) to use
/// </param>
public IncompleteComponent(IHaveNoImplementation noImplementation) { }
}
#endregion // class IncompleteComponent
#region class NeedHello
/// <summary>Component that needs an implementation of the hello contract</summary>
public class NeedHello : IWorldContract {
/// <summary>Initializes the component</summary>
/// <param name="helloContract">
/// Implementation of the hello contract that will be used
/// </param>
public NeedHello(IHelloContract helloContract) { }
}
#endregion // class NeedHello
#region class NeedWorld
/// <summary>Component that needs an implementation of the world contract</summary>
public class NeedWorld : IHelloContract {
/// <summary>Initializes the component</summary>
/// <param name="worldContract">
/// Implementation of the world contract that will be used
/// </param>
public NeedWorld(IWorldContract worldContract) { }
}
#endregion // class NeedWorld
/// <summary>
/// Tests whether the GetComponents() method behaves correctly if it is used
/// without any assemblies loaded
/// </summary>
[Test]
public void TestGetComponentsWithoutAssembly() {
ServiceManager serviceManager = new ServiceManager(new PredefinedTypeLister());
Assert.That(serviceManager.GetComponents<IDisposable>(), Is.Empty);
}
/// <summary>
/// Tests whether the GetComponents() method can locate a simple component
/// </summary>
[Test]
public void TestGetComponents() {
RepositoryTypeLister typeLister = new RepositoryTypeLister();
ServiceManager serviceManager = new ServiceManager(typeLister);
typeLister.Repository.AddAssembly(typeof(ServiceManagerTest).Assembly);
Assert.That(
serviceManager.GetComponents<IHelloContract>(),
Has.Member(typeof(HelloComponent)).And.Member(typeof(WorldComponent))
);
}
/// <summary>
/// Tests whether the GetComponents() method correctly determines which
/// components can have their dependencies completely provided.
/// </summary>
[Test]
public void TestFilteredGetComponents() {
RepositoryTypeLister typeLister = new RepositoryTypeLister();
ServiceManager serviceManager = new ServiceManager(typeLister);
typeLister.Repository.AddAssembly(typeof(ServiceManagerTest).Assembly);
Assert.That(
serviceManager.GetComponents<IWorldContract>(false),
Has.Member(typeof(WorldComponent)).And.Member(typeof(IncompleteComponent))
);
Assert.That(
serviceManager.GetComponents<IWorldContract>(true),
Has.Member(typeof(WorldComponent)).And.No.Member(typeof(IncompleteComponent))
);
}
/// <summary>
/// Tests whether the GetComponents() method can cope with two components
/// that have a circular dependency through their services.
/// </summary>
[Test]
public void TestCircularDependency() {
}
/// <summary>
/// Verifies that the right exception is thrown if the non-generic GetService()
/// is used on a value type
/// </summary>
[Test]
public void TestGetComponentOnValueType() {
RepositoryTypeLister typeLister = new RepositoryTypeLister();
ServiceManager serviceManager = new ServiceManager(typeLister);
typeLister.Repository.AddAssembly(typeof(int).Assembly);
Assert.Throws<ArgumentException>(
delegate() { serviceManager.GetService(typeof(int)); }
);
}
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER
#endif // UNITTEST

View File

@ -1,326 +0,0 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 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;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using Nuclex.Support.Plugins;
#if ENABLE_SERVICEMANAGER
namespace Nuclex.Support.Services {
// Allow Dependency on Container
// public Foo(IServiceProvider serviceProvider)
// public Foo(IserviceLocator serviceLocator)
// public Foo(Container container)
/// <summary>
/// Inversion of Control container that manages the services of an application
/// </summary>
/// <remarks>
/// <para>
/// This is a very lightweight and simple inversion of control container that
/// relieves components of their duty to track down implementations for the services
/// they require to function. It will help with lazy initialization and prevent
/// components from becoming cross-linked balls of spaghetti references.
/// </para>
/// <para>
/// Here's a short list of the terms used throughout this container and their
/// specific meaning in this context.
/// </para>
/// <para>
/// <list type="bullet">
/// <item>
/// <term>Service</term>
/// <description>
/// Defined by an interface (service contract) and provided by a component
/// that implements the service contract. A service provides some kind of
/// utility to the application, for example it could provide access to
/// a data base or allow other components to control certain aspects of
/// the application.
/// </description>
/// </item>
/// <item>
/// <term>Contract</term>
/// <description>
/// Interface defining the behavior that a service implementation has to
/// follow. In order for a component to become a suitable candidate for
/// providing a specific service, it has to implement the service contract
/// interface and should rigorously follow its specifications.
/// </description>
/// </item>
/// <item>
/// <term>Component</term>
/// <description>
/// A component is simply a class that implements one or more service
/// contracts. The service manager will created instances of these classes
/// when all their dependencies can be provided for and an implementation
/// of their service contract is requested.
/// </description>
/// </item>
/// </list>
/// </para>
/// </remarks>
public partial class ServiceManager : IServiceProvider {
#region class Contract
/// <summary>Stores the settings for an individual contract</summary>
private class Contract {
/// <summary>
/// Factory by which instances of the contract implementation can be created
/// </summary>
public IAbstractFactory Factory;
/// <summary>How instances of the implementation are to be managed</summary>
public Instancing Instancing;
/// <summary>Single global instance of the contract implementation</summary>
/// <remarks>
/// Used only if <paramref name="Instancing" /> is set to Singleton
/// </remarks>
public object SingletonInstance;
/// <summary>Thread-local instance of the contract implementation</summary>
/// <remarks>
/// Used only if <paramref name="Instancing" />is set to InstancePerThread
/// </remarks>
public object ThreadLocalInstance {
get {
initializeThreadLocalData();
return Thread.GetData(this.threadLocalDataSlot);
}
set {
initializeThreadLocalData();
Thread.SetData(this.threadLocalDataSlot, value);
}
}
/// <summary>Initializes the thread-local data slot</summary>
private void initializeThreadLocalData() {
if(this.threadLocalDataSlot == null) {
lock(this) {
if(this.threadLocalDataSlot == null) {
this.threadLocalDataSlot = Thread.AllocateDataSlot();
}
}
}
}
/// <summary>Arguments to be passed to the component constructor</summary>
private Dictionary<string, object> arguments;
/// <summary>Data slot for thread local storage</summary>
/// <remarks>
/// We're using an explicit data slot because the ThreadStaticAttribute class
/// can only be used on static fields and also because this class is not
/// supported by the .NET Compact Framework.
/// </remarks>
private volatile LocalDataStoreSlot threadLocalDataSlot;
}
#endregion // class Contract
#if WINDOWS
/// <summary>Initializes a new service manager</summary>
/// <remarks>
/// This overload will automatically use a type lister that causes all types
/// in all loaded assemblies of the calling app domain to be considered
/// by the service manager for obtaining contract implementations.
/// </remarks>
public ServiceManager() : this(new AppDomainTypeLister()) { }
#endif // WINDOWS
/// <summary>Initializes a new service manager</summary>
/// <param name="typeLister">
/// Type lister providing the types considered by the service manager for
/// obtaining contract implementations.
/// </param>
public ServiceManager(ITypeLister typeLister) {
this.typeLister = typeLister;
this.contracts = new Dictionary<Type, Contract>();
}
/// <summary>
/// Returns all available implementations for the specified contract
/// </summary>
/// <returns>
/// A new enumerator for the available contract implementations
/// </returns>
public IEnumerable<Type> GetComponents<ContractType>() where ContractType : class {
Type contractType = typeof(ContractType);
foreach(Type checkedType in this.typeLister.GetTypes()) {
bool isImplementationOfContract =
(!checkedType.IsAbstract) &&
contractType.IsAssignableFrom(checkedType);
if(isImplementationOfContract) {
yield return checkedType;
}
}
}
/// <summary>
/// Returns all available implementations for the specified contract
/// </summary>
/// <param name="completeOnly">
/// If true, only services whose dependencies can be completely
/// satisfied by the container are returned.
/// </param>
/// <returns>
/// A new enumerator for the available contract implementations
/// </returns>
public IEnumerable<Type> GetComponents<ContractType>(bool completeOnly)
where ContractType : class {
if(completeOnly) {
return filterCompleteComponents(GetComponents<ContractType>());
} else {
return GetComponents<ContractType>();
}
}
/// <summary>
/// Filters a list of components so only components whose dependencies can be
/// completely provided are enumerated
/// </summary>
/// <param name="types">Enumerable type list that will be filtered</param>
/// <returns>
/// Only those components whose dependencies can be completely provided
/// </returns>
private IEnumerable<Type> filterCompleteComponents(IEnumerable<Type> types) {
foreach(Type type in types) {
bool isCandidate =
(!type.IsValueType) &&
(!type.IsAbstract) &&
(type.IsPublic || type.IsNestedPublic);
if(isCandidate) {
ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public);
// If a contract has been
Contract contract;
if(this.contracts.TryGetValue(type, out contract)) {
yield return type;
} else {
}
yield return type;
}
}
}
/// <summary>
/// Allows the adjustment of the container's behavior in regard to
/// the specified contract
/// </summary>
/// <typeparam name="ContractType">
/// Contract for which the behavior will be adjusted
/// </typeparam>
/// <returns>
/// A context object through which the behavior of the container can be
/// adjusted for the specified type
/// </returns>
public ForContext<ContractType> For<ContractType>() where ContractType : class {
return new ForContext<ContractType>(this);
}
/// <summary>
/// Allows the adjustment of the container's behavior in regard to
/// the specified contract
/// </summary>
/// <param name="contractType">
/// Contract for which the behavior will be adjusted
/// </param>
/// <returns>
/// A context object through which the behavior of the container can be
/// adjusted for the specified type
/// </returns>
public ForContext For(Type contractType) {
return new ForContext(this, contractType);
}
/// <summary>Retrieves the service of the specified type</summary>
/// <typeparam name="ContractType">
/// Contract for which the service will be retrieved
/// </typeparam>
/// <returns>The service for the specified contract</returns>
public ContractType GetService<ContractType>() where ContractType : class {
return (ContractType)GetService(typeof(ContractType));
}
/// <summary>Retrieves the service of the specified type</summary>
/// <param name="contractType">
/// Contract for which the service will be retrieved
/// </param>
/// <returns>The service for the specified contract</returns>
public object GetService(Type contractType) {
Contract c = resolveContract(contractType);
return c.Factory.CreateInstance(); // TODO: Honor the contract settings
}
/// <summary>
/// Resolves all dependencies required to create a service for a contract
/// </summary>
/// <param name="contractType">
/// Type of contract for which to resolve the implementation
/// </param>
/// <returns>The settings for the contract including a valid factory</returns>
private Contract resolveContract(Type contractType) {
if(contractType.IsValueType) {
throw new ArgumentException(
"Contracts have to be interfaces or classes", "contractType"
);
}
/*
Contract contract;
if(this.contracts.TryGetValue(contractType, out contract)) {
return contract;
}
*/
throw new NotImplementedException();
}
/// <summary>Lists all types partaking in the dependency injection</summary>
private ITypeLister typeLister;
/// <summary>Dictionary with settings for each individual contract</summary>
private Dictionary<Type, Contract> contracts;
}
} // namespace Nuclex.Support.Services
#endif // ENABLE_SERVICEMANAGER