diff --git a/Nuclex.Support (Xbox 360).csproj b/Nuclex.Support (Xbox 360).csproj
index c02e09e..d01ac1e 100644
--- a/Nuclex.Support (Xbox 360).csproj
+++ b/Nuclex.Support (Xbox 360).csproj
@@ -126,14 +126,14 @@
AppDomainTypeLister.cs
-
-
- AssemblyTypeLister.cs
+
+
+ ExplicitTypeLister.cs
-
- PredefinedTypeLister.cs
+
+ MultiAssemblyTypeLister.cs
@@ -143,6 +143,9 @@
RepositoryTypeLister.cs
+
+ ServiceManager.cs
+
ServiceManager.cs
@@ -256,7 +259,7 @@
ServiceManager.cs
-
+
Shared.cs
diff --git a/Nuclex.Support.csproj b/Nuclex.Support.csproj
index 7bdb582..443ddae 100644
--- a/Nuclex.Support.csproj
+++ b/Nuclex.Support.csproj
@@ -108,14 +108,14 @@
AppDomainTypeLister.cs
-
-
- AssemblyTypeLister.cs
+
+
+ ExplicitTypeLister.cs
-
- PredefinedTypeLister.cs
+
+ MultiAssemblyTypeLister.cs
@@ -125,6 +125,9 @@
RepositoryTypeLister.cs
+
+ ServiceManager.cs
+
ServiceManager.cs
@@ -238,7 +241,7 @@
ServiceManager.cs
-
+
Shared.cs
diff --git a/Source/Services/AppDomainTypeLister.cs b/Source/Services/AppDomainTypeLister.cs
index 42c3c4c..4956d4f 100644
--- a/Source/Services/AppDomainTypeLister.cs
+++ b/Source/Services/AppDomainTypeLister.cs
@@ -27,7 +27,7 @@ namespace Nuclex.Support.Services {
#if !XBOX360
/// Lists the types of all assemblies in an application domain
- public class AppDomainTypeLister : AssemblyTypeLister {
+ public class AppDomainTypeLister : MultiAssemblyTypeLister {
///
/// Initializes a new application domain type lister using the application domain
diff --git a/Source/Services/PredefinedTypeLister.Test.cs b/Source/Services/ExplicitTypeLister.Test.cs
similarity index 68%
rename from Source/Services/PredefinedTypeLister.Test.cs
rename to Source/Services/ExplicitTypeLister.Test.cs
index 187d165..f4839ff 100644
--- a/Source/Services/PredefinedTypeLister.Test.cs
+++ b/Source/Services/ExplicitTypeLister.Test.cs
@@ -30,7 +30,7 @@ namespace Nuclex.Support.Services {
/// Unit Test for the predefined type lister
[TestFixture]
- public class PredefinedTypeListerTest {
+ public class ExplicitTypeListerTest {
///
/// Verifies that the type lister correctly takes over a list of types
@@ -38,13 +38,13 @@ namespace Nuclex.Support.Services {
///
[Test]
public void TestPredefinedTypesFromParams() {
- ITypeLister testLister = new PredefinedTypeLister(
- typeof(PredefinedTypeListerTest), typeof(TestAttribute)
+ ITypeLister testLister = new ExplicitTypeLister(
+ typeof(ExplicitTypeListerTest), typeof(TestAttribute)
);
Assert.That(
testLister.GetTypes(),
- Has.Member(typeof(PredefinedTypeListerTest)).And.Member(typeof(TestAttribute))
+ Has.Member(typeof(ExplicitTypeListerTest)).And.Member(typeof(TestAttribute))
);
}
@@ -54,11 +54,11 @@ namespace Nuclex.Support.Services {
///
[Test]
public void TestPredefinedTypesFromEnumerable() {
- IEnumerable types = typeof(PredefinedTypeListerTest).Assembly.GetTypes();
- ITypeLister testLister = new PredefinedTypeLister(types);
+ IEnumerable types = typeof(ExplicitTypeListerTest).Assembly.GetTypes();
+ ITypeLister testLister = new ExplicitTypeLister(types);
Assert.That(
- testLister.GetTypes(), Has.Member(typeof(PredefinedTypeListerTest))
+ testLister.GetTypes(), Has.Member(typeof(ExplicitTypeListerTest))
);
}
@@ -67,16 +67,16 @@ namespace Nuclex.Support.Services {
///
[Test]
public void TestRemoveTypesFromLister() {
- PredefinedTypeLister testLister = new PredefinedTypeLister(
- typeof(PredefinedTypeListerTest).Assembly.GetTypes()
+ ExplicitTypeLister testLister = new ExplicitTypeLister(
+ typeof(ExplicitTypeListerTest).Assembly.GetTypes()
);
Assert.That(
- testLister.GetTypes(), Has.Member(typeof(PredefinedTypeListerTest))
+ testLister.GetTypes(), Has.Member(typeof(ExplicitTypeListerTest))
);
- testLister.Types.Remove(typeof(PredefinedTypeListerTest));
+ testLister.Types.Remove(typeof(ExplicitTypeListerTest));
Assert.That(
- testLister.GetTypes(), Has.No.Member(typeof(PredefinedTypeListerTest))
+ testLister.GetTypes(), Has.No.Member(typeof(ExplicitTypeListerTest))
);
}
@@ -85,7 +85,7 @@ namespace Nuclex.Support.Services {
///
[Test]
public void TestAddTypesToLister() {
- PredefinedTypeLister testLister = new PredefinedTypeLister();
+ ExplicitTypeLister testLister = new ExplicitTypeLister();
Assert.That(
testLister.GetTypes(), Has.No.Member(typeof(TestAttribute))
diff --git a/Source/Services/PredefinedTypeLister.cs b/Source/Services/ExplicitTypeLister.cs
similarity index 88%
rename from Source/Services/PredefinedTypeLister.cs
rename to Source/Services/ExplicitTypeLister.cs
index cc539f4..728f32b 100644
--- a/Source/Services/PredefinedTypeLister.cs
+++ b/Source/Services/ExplicitTypeLister.cs
@@ -25,17 +25,17 @@ using System.Text;
namespace Nuclex.Support.Services {
/// Type lister that returns a predefined list of types
- public class PredefinedTypeLister : ITypeLister {
+ public class ExplicitTypeLister : ITypeLister {
/// Initializes a new predefined type lister
/// Types the predefined type lister will list
- public PredefinedTypeLister(params Type[] types) {
+ public ExplicitTypeLister(params Type[] types) {
this.types = new List(types);
}
/// Initializes a new predefined type lister
/// Types the predefined type lister will list
- public PredefinedTypeLister(IEnumerable types) {
+ public ExplicitTypeLister(IEnumerable types) {
this.types = new List(types);
}
diff --git a/Source/Services/AssemblyTypeLister.Test.cs b/Source/Services/MultiAssemblyTypeLister.Test.cs
similarity index 80%
rename from Source/Services/AssemblyTypeLister.Test.cs
rename to Source/Services/MultiAssemblyTypeLister.Test.cs
index a2fdb39..5247549 100644
--- a/Source/Services/AssemblyTypeLister.Test.cs
+++ b/Source/Services/MultiAssemblyTypeLister.Test.cs
@@ -30,12 +30,12 @@ namespace Nuclex.Support.Services {
/// Unit Test for the cached assembly type lister
[TestFixture]
- public class AssemblyTypeListerTest {
+ public class MultiAssemblyTypeListerTest {
#region class TestAssemblyTypeLister
/// Test implementation of a cached assembly type lister
- private class TestAssemblyTypeLister : AssemblyTypeLister {
+ private class TestAssemblyTypeLister : MultiAssemblyTypeLister {
/// Initializes a new test assembly type lister
/// Assemblies whose types will be listed
@@ -68,11 +68,11 @@ namespace Nuclex.Support.Services {
[Test]
public void TestAssemblyListGeneration() {
TestAssemblyTypeLister testLister = new TestAssemblyTypeLister(
- typeof(AssemblyTypeListerTest).Assembly
+ typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
- testLister.GetTypes(), Has.Member(typeof(AssemblyTypeListerTest))
+ testLister.GetTypes(), Has.Member(typeof(MultiAssemblyTypeListerTest))
);
}
@@ -89,17 +89,17 @@ namespace Nuclex.Support.Services {
Assert.That(
testLister.GetTypes(),
- Has.Member(typeof(TestAttribute)).And.Not.Member(typeof(AssemblyTypeListerTest))
+ Has.Member(typeof(TestAttribute)).And.Not.Member(typeof(MultiAssemblyTypeListerTest))
);
testLister.ReplaceAssemblyList(
typeof(Assembly).Assembly,
- typeof(AssemblyTypeListerTest).Assembly
+ typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(),
- Has.Member(typeof(AssemblyTypeListerTest)).And.Not.Member(typeof(TestAttribute))
+ Has.Member(typeof(MultiAssemblyTypeListerTest)).And.Not.Member(typeof(TestAttribute))
);
}
@@ -112,22 +112,22 @@ namespace Nuclex.Support.Services {
TestAssemblyTypeLister testLister = new TestAssemblyTypeLister(
typeof(Assembly).Assembly,
typeof(TestAttribute).Assembly,
- typeof(AssemblyTypeListerTest).Assembly
+ typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(),
- Has.Member(typeof(TestAttribute)).And.Member(typeof(AssemblyTypeListerTest))
+ Has.Member(typeof(TestAttribute)).And.Member(typeof(MultiAssemblyTypeListerTest))
);
testLister.ReplaceAssemblyList(
typeof(Assembly).Assembly,
- typeof(AssemblyTypeListerTest).Assembly
+ typeof(MultiAssemblyTypeListerTest).Assembly
);
Assert.That(
testLister.GetTypes(),
- Has.Member(typeof(AssemblyTypeListerTest)).And.Not.Member(typeof(TestAttribute))
+ Has.Member(typeof(MultiAssemblyTypeListerTest)).And.Not.Member(typeof(TestAttribute))
);
}
diff --git a/Source/Services/AssemblyTypeLister.cs b/Source/Services/MultiAssemblyTypeLister.cs
similarity index 74%
rename from Source/Services/AssemblyTypeLister.cs
rename to Source/Services/MultiAssemblyTypeLister.cs
index 82ab8bd..7d4aec7 100644
--- a/Source/Services/AssemblyTypeLister.cs
+++ b/Source/Services/MultiAssemblyTypeLister.cs
@@ -25,7 +25,7 @@ using System.Reflection;
namespace Nuclex.Support.Services {
/// Lists all types in a changing set of assemblies
- public abstract class AssemblyTypeLister : ITypeLister {
+ public abstract class MultiAssemblyTypeLister : ITypeLister {
#region class AssemblyTypes
@@ -50,7 +50,7 @@ namespace Nuclex.Support.Services {
#endregion // class AssemblyTypes
/// Initializes a new assembly type lister
- public AssemblyTypeLister() {
+ public MultiAssemblyTypeLister() {
this.assemblyTypes = new LinkedList();
}
@@ -97,7 +97,10 @@ namespace Nuclex.Support.Services {
} 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.
+ // 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 existingNode = node;
while(existingNode.Value.Assembly != assembly) {
existingNode = existingNode.Next;
@@ -106,17 +109,33 @@ namespace Nuclex.Support.Services {
}
}
- // If this assembly wasn't found in the cache, add it in the same order
- // it was returned by the enumerator.
+ // 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) { // Cached assemblies were skipped, reorder
+
+ } 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 { // Everything as expected
+
+ } 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;
+
}
}
diff --git a/Source/Services/ProgressTracking/ProgressTrackingComponent.cs b/Source/Services/ProgressTracking/ProgressTrackingComponent.cs
index f610a19..0ec7b32 100644
--- a/Source/Services/ProgressTracking/ProgressTrackingComponent.cs
+++ b/Source/Services/ProgressTracking/ProgressTrackingComponent.cs
@@ -25,7 +25,8 @@ using Nuclex.Support.Tracking;
namespace Nuclex.Support.Services.ProgressTracking {
-#if false
+#if ENABLE_SERVICEMANAGER
+
/// Tracks the progress of running background processes
public class ProgressTrackingComponent :
IProgressCollectingService,
@@ -71,6 +72,7 @@ namespace Nuclex.Support.Services.ProgressTracking {
}
}
-#endif
+
+#endif // ENABLE_SERVICEMANAGER
} // namespace Nuclex.Support.Services.ProgressTracking
diff --git a/Source/Services/RepositoryTypeLister.cs b/Source/Services/RepositoryTypeLister.cs
index 826eb32..0cfaa88 100644
--- a/Source/Services/RepositoryTypeLister.cs
+++ b/Source/Services/RepositoryTypeLister.cs
@@ -29,7 +29,7 @@ namespace Nuclex.Support.Services {
///
/// Lists the types of all assemblies contained in an assembly repository
///
- public class RepositoryTypeLister : AssemblyTypeLister {
+ public class RepositoryTypeLister : MultiAssemblyTypeLister {
///
/// Initializes a new repository type lister using a new repository
diff --git a/Source/Services/ServiceManager.Analyzer.cs b/Source/Services/ServiceManager.Analyzer.cs
new file mode 100644
index 0000000..6488831
--- /dev/null
+++ b/Source/Services/ServiceManager.Analyzer.cs
@@ -0,0 +1,53 @@
+#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
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Nuclex.Support.Services {
+
+#if ENABLE_SERVICEMANAGER
+
+ partial class ServiceManager {
+
+ #region class Analyzer
+
+ /// Analyzes Component dependencies
+ private static class Analyzer {
+
+
+
+ public static KeyValuePair[] GetRequirements(ConstructorInfo constructor) {
+ ParameterInfo[] parameters = constructor.GetParameters();
+ //parameters[0].IsOptional
+
+ return null;
+ }
+
+ }
+
+ #endregion // class Analyzer
+
+ }
+
+#endif // ENABLE_SERVICEMANAGER
+
+} // namespace Nuclex.Support.Services
diff --git a/Source/Services/ServiceManager.For.cs b/Source/Services/ServiceManager.For.cs
index a6f10c9..414389d 100644
--- a/Source/Services/ServiceManager.For.cs
+++ b/Source/Services/ServiceManager.For.cs
@@ -24,7 +24,8 @@ using System.Text;
namespace Nuclex.Support.Services {
-#if false
+#if ENABLE_SERVICEMANAGER
+
partial class ServiceManager {
#region class ForContext
@@ -109,6 +110,7 @@ namespace Nuclex.Support.Services {
#endregion // class ForContext<>
}
-#endif
+
+#endif // ENABLE_SERVICEMANAGER
} // namespace Nuclex.Support.Services
diff --git a/Source/Services/ServiceManager.Test.cs b/Source/Services/ServiceManager.Test.cs
index b7a52cf..01edae2 100644
--- a/Source/Services/ServiceManager.Test.cs
+++ b/Source/Services/ServiceManager.Test.cs
@@ -21,12 +21,16 @@ License along with this library
using System;
using System.IO;
+using Nuclex.Support.Plugins;
+
#if UNITTEST
using NUnit.Framework;
namespace Nuclex.Support.Services {
+#if ENABLE_SERVICEMANAGER
+
/// Unit Test for the service manager class
[TestFixture]
public class ServiceManagerTest {
@@ -117,14 +121,13 @@ namespace Nuclex.Support.Services {
#endregion // class NeedWorld
-#if false
///
/// Tests whether the GetComponents() method behaves correctly if it is used
/// without any assemblies loaded
///
[Test]
public void TestGetComponentsWithoutAssembly() {
- ServiceManager serviceManager = new ServiceManager();
+ ServiceManager serviceManager = new ServiceManager(new PredefinedTypeLister());
Assert.That(serviceManager.GetComponents(), Is.Empty);
}
@@ -133,8 +136,9 @@ namespace Nuclex.Support.Services {
///
[Test]
public void TestGetComponents() {
- ServiceManager serviceManager = new ServiceManager();
- serviceManager.Repository.AddAssembly(typeof(ServiceManagerTest).Assembly);
+ RepositoryTypeLister typeLister = new RepositoryTypeLister();
+ ServiceManager serviceManager = new ServiceManager(typeLister);
+ typeLister.Repository.AddAssembly(typeof(ServiceManagerTest).Assembly);
Assert.That(
serviceManager.GetComponents(),
@@ -148,8 +152,9 @@ namespace Nuclex.Support.Services {
///
[Test]
public void TestFilteredGetComponents() {
- ServiceManager serviceManager = new ServiceManager();
- serviceManager.Repository.AddAssembly(typeof(ServiceManagerTest).Assembly);
+ RepositoryTypeLister typeLister = new RepositoryTypeLister();
+ ServiceManager serviceManager = new ServiceManager(typeLister);
+ typeLister.Repository.AddAssembly(typeof(ServiceManagerTest).Assembly);
Assert.That(
serviceManager.GetComponents(false),
@@ -174,18 +179,21 @@ namespace Nuclex.Support.Services {
/// Verifies that the right exception is thrown if the non-generic GetService()
/// is used on a value type
///
- [Test]
+ [Test]
public void TestGetComponentOnValueType() {
- ServiceManager serviceManager = new ServiceManager();
- serviceManager.Repository.AddAssembly(typeof(int).Assembly);
+ RepositoryTypeLister typeLister = new RepositoryTypeLister();
+ ServiceManager serviceManager = new ServiceManager(typeLister);
+ typeLister.Repository.AddAssembly(typeof(int).Assembly);
Assert.Throws(
delegate() { serviceManager.GetService(typeof(int)); }
);
}
-#endif
+
}
+#endif // ENABLE_SERVICEMANAGER
+
} // namespace Nuclex.Support.Services
#endif // UNITTEST
diff --git a/Source/Services/ServiceManager.cs b/Source/Services/ServiceManager.cs
index d9161ba..b161a14 100644
--- a/Source/Services/ServiceManager.cs
+++ b/Source/Services/ServiceManager.cs
@@ -28,7 +28,7 @@ using Nuclex.Support.Plugins;
namespace Nuclex.Support.Services {
-#if false
+#if ENABLE_SERVICEMANAGER
// Allow Dependency on Container
// public Foo(IServiceProvider serviceProvider)
@@ -163,11 +163,7 @@ namespace Nuclex.Support.Services {
///
public ServiceManager(ITypeLister typeLister) {
this.typeLister = typeLister;
-
- resolveContractMethod = GetType().GetMethod(
- "resolve", BindingFlags.NonPublic | BindingFlags.Instance
- );
- Debug.Assert(this.resolveContractMethod.IsGenericMethodDefinition);
+ this.contracts = new Dictionary();
}
///
@@ -219,10 +215,30 @@ namespace Nuclex.Support.Services {
///
private IEnumerable filterCompleteComponents(IEnumerable types) {
foreach(Type type in types) {
- yield return type;
- }
- yield break;
+ 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;
+
+ }
+
+ }
}
///
@@ -256,12 +272,12 @@ namespace Nuclex.Support.Services {
}
/// Retrieves the service of the specified type
- ///
+ ///
/// Contract for which the service will be retrieved
- ///
+ ///
/// The service for the specified contract
public ContractType GetService() where ContractType : class {
- throw new NotImplementedException();
+ return (ContractType)GetService(typeof(ContractType));
}
/// Retrieves the service of the specified type
@@ -270,36 +286,34 @@ namespace Nuclex.Support.Services {
///
/// The service for the specified contract
public object GetService(Type contractType) {
- MethodInfo methodInstance = this.resolveContractMethod.MakeGenericMethod(
- new Type[] { contractType }
- );
- return methodInstance.Invoke(this, null);
+ Contract c = resolveContract(contractType);
+ return c.Factory.CreateInstance(); // TODO: Honor the contract settings
}
///
/// Resolves all dependencies required to create a service for a contract
///
- ///
+ ///
/// Type of contract for which to resolve the implementation
- ///
+ ///
/// The settings for the contract including a valid factory
- private Contract resolveContract() where ContractType : class {
- throw new NotImplementedException();
- }
-
private Contract resolveContract(Type contractType) {
- Contract contract;
- if(this.contracts.TryGetValue(contractType, out contract)) {
- return contract;
+ 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();
}
- /// MethodInfo for the resolve() method of this instance
- private MethodInfo resolveContractMethod;
/// Lists all types partaking in the dependency injection
private ITypeLister typeLister;
/// Dictionary with settings for each individual contract
@@ -307,6 +321,6 @@ namespace Nuclex.Support.Services {
}
-#endif
+#endif // ENABLE_SERVICEMANAGER
} // namespace Nuclex.Support.Services