From cb6960eb15e056147a7945b8899137387a330125 Mon Sep 17 00:00:00 2001 From: David Rundle Date: Sun, 9 Jun 2013 19:33:42 +0100 Subject: [PATCH] A start of the API refactoring (Breaking changes) Please read all of the obsolete comments ( in most cases it is a rename ) note: there are some spelling corrections note: the Registration class is being obsoleted, and replaced with a very similar RegisterBase class, in each implementation of integration such as Boxes.Windsor, they should supply their own Register implementation. This was to provide a better and strongly class/experience --- .../Boxes.Integration.csproj | 5 +- src/Boxes.Integration/BoxesWrapperBase.cs | 7 ++ .../ContainerSetup/BoxesContainerSetupBase.cs | 13 ++-- .../{RegisterWith.cs => Contracts.cs} | 12 ++- .../ContainerSetup/IBoxesContainerSetup.cs | 11 ++- .../ContainerSetup/IRegister.cs | 74 ++++++++++++++++++ .../ContainerSetup/RegisterBase.cs | 77 +++++++++++++++++++ .../ContainerSetup/RegisterContext.cs | 22 ++++++ .../ContainerSetup/Registration.cs | 31 +++++--- .../ContainerSetup/RegistrationMeta.cs | 31 +++++++- .../Setup/BoxesIntergrationSetup.cs | 3 - 11 files changed, 257 insertions(+), 29 deletions(-) rename src/Boxes.Integration/ContainerSetup/{RegisterWith.cs => Contracts.cs} (88%) create mode 100644 src/Boxes.Integration/ContainerSetup/IRegister.cs create mode 100644 src/Boxes.Integration/ContainerSetup/RegisterBase.cs create mode 100644 src/Boxes.Integration/ContainerSetup/RegisterContext.cs diff --git a/src/Boxes.Integration/Boxes.Integration.csproj b/src/Boxes.Integration/Boxes.Integration.csproj index e59a41d..e196c6a 100644 --- a/src/Boxes.Integration/Boxes.Integration.csproj +++ b/src/Boxes.Integration/Boxes.Integration.csproj @@ -45,6 +45,9 @@ + + + @@ -70,7 +73,7 @@ - + diff --git a/src/Boxes.Integration/BoxesWrapperBase.cs b/src/Boxes.Integration/BoxesWrapperBase.cs index 85677d4..61e0c67 100644 --- a/src/Boxes.Integration/BoxesWrapperBase.cs +++ b/src/Boxes.Integration/BoxesWrapperBase.cs @@ -31,11 +31,16 @@ public abstract class BoxesWrapperBase : IBoxesWrapper //issue is around the containers, a subset allow to deletions of registrations //an other way is to restart the app and only register the required packages with the IoC //the second way can be supported by coding a module + //favoured way, use of child container, will need to re-initialise the container (delete, create a new one) //TODO: migrations //updates of a module will require a restart, currently the Loaders do not support //app domains. they do offer a level of isolation + //TODO: Multi-tenancy + //use child containers to handle tenants. implement a IProcess (consider PLinq) to register + //the correct packages with the correct child container. + /// /// the main process line, add tasks to this, and they will be executed /// in the order defined by @@ -123,6 +128,8 @@ public virtual void LoadPackages() //process extensions first (in complete, before running the rest of the package or process) _setup.ExtensionRunner.Execute(loader.Packages).Force(); + //TODO: push the following into a separate interface + //filter out the packages which are not in use. IEnumerable filteredPackages = _setup.GlobalPackagesFilter == null diff --git a/src/Boxes.Integration/ContainerSetup/BoxesContainerSetupBase.cs b/src/Boxes.Integration/ContainerSetup/BoxesContainerSetupBase.cs index e0fb0ab..76f7d39 100644 --- a/src/Boxes.Integration/ContainerSetup/BoxesContainerSetupBase.cs +++ b/src/Boxes.Integration/ContainerSetup/BoxesContainerSetupBase.cs @@ -25,16 +25,17 @@ public abstract class BoxesContainerSetupBase : IBoxesContainerSetup public abstract void RegisterLifeStyle(); - public void RegisterLifeStyle(Registration registration) + public void RegisterLifeStyle(IRegister registration) { - RegisterLifeStyle(registration.RegistrationMeta); + AddRegistration(registration); } - protected abstract void RegisterLifeStyle(RegistrationMeta registration); - - protected void AddRegistrationTask(IBoxesTask registrationTask) + public void AddRegistration(IRegister registration) { - _registraionTasks.Add(registrationTask); + var task = CreateRegisterTask(registration.RegistrationMeta); + _registraionTasks.Add(task); } + + protected abstract IBoxesTask CreateRegisterTask(RegistrationMeta registration); } } \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/RegisterWith.cs b/src/Boxes.Integration/ContainerSetup/Contracts.cs similarity index 88% rename from src/Boxes.Integration/ContainerSetup/RegisterWith.cs rename to src/Boxes.Integration/ContainerSetup/Contracts.cs index 6e4454d..d039379 100644 --- a/src/Boxes.Integration/ContainerSetup/RegisterWith.cs +++ b/src/Boxes.Integration/ContainerSetup/Contracts.cs @@ -13,10 +13,12 @@ // limitations under the License. namespace Boxes.Integration.ContainerSetup { + using System; + /// - /// Register with which services + /// Register with which service contracts /// - public enum RegisterWith + public enum Contracts { /// /// All the interfaces @@ -38,4 +40,10 @@ public enum RegisterWith /// SelfAndAllInterfaces } + + [Obsolete("Use Contracts", true)] + public enum RegisterWith + { + + } } \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/IBoxesContainerSetup.cs b/src/Boxes.Integration/ContainerSetup/IBoxesContainerSetup.cs index 30439ac..fbe8477 100644 --- a/src/Boxes.Integration/ContainerSetup/IBoxesContainerSetup.cs +++ b/src/Boxes.Integration/ContainerSetup/IBoxesContainerSetup.cs @@ -32,13 +32,20 @@ public interface IBoxesContainerSetup /// /// The lifestyle manager to use /// The Dependency interface to register with the lifecycle - [Obsolete("use the other overload")] + [Obsolete("use AddRegistration", true)] void RegisterLifeStyle(); /// /// Register a type (can be as simple as does it implement a Dependency or to apply a filter) /// /// The registration with details on how setup the IoC with the types which match the where clause - void RegisterLifeStyle(Registration registration); + [Obsolete("use AddRegistration")] + void RegisterLifeStyle(IRegister registration); + + /// + /// Register a type (can be as simple as does it implement a Dependency or to apply a filter) + /// + /// The registration with details on how setup the IoC with the types which match the where clause + void AddRegistration(IRegister registration); } } \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/IRegister.cs b/src/Boxes.Integration/ContainerSetup/IRegister.cs new file mode 100644 index 0000000..ee686ab --- /dev/null +++ b/src/Boxes.Integration/ContainerSetup/IRegister.cs @@ -0,0 +1,74 @@ +namespace Boxes.Integration.ContainerSetup +{ + using System; + using System.Collections.Generic; + + /// + /// This class provides a mechanism to setup the registration of types with the underlying IoC. + /// + public interface IRegister + { + /// + /// meta information about the registration + /// + RegistrationMeta RegistrationMeta { get; } + } + + /// + /// This class provides a mechanism to setup the registration of types with the underlying IoC. + /// + /// The signature for the scope/lifestyle + /// the IoC direct configuration for the current registration + public interface IRegister : IRegister + { + /// + /// apply a filter (pattern) to find which types this registration will apply too + /// + /// the pattern to find the types this registration applies too + IRegister Where(Predicate where); + + /// + /// which contracts to associate the current type with + /// + /// select the appropriate contracts to register this class with + IRegister AssociateWith(Contracts contracts); + + /// + /// which contracts to associate the current type with + /// + /// provide a list of contracts to associate the current type with + IRegister AssociateWith(Func> contracts); + + /// + /// which contracts to associate the current type with + /// + /// provide a list of contracts to associate the current type with + IRegister AssociateWith(IEnumerable contracts); + + /// + /// supply a ctor to use, apply this in the Configure Method, as this will allow direct access + /// to the actual IoC's registration + /// + /// the ctor to use + [Obsolete("not all IoC's support this", true)] + IRegister Ctor(Func factoryMethod); + + /// + /// the life style of the type (scope and lifestyle are considered to be the same thing at this point) + /// + /// the life style to use + IRegister LifeStyle(TScope lifeStyle); + + /// + /// the scope of the type (scope and lifestyle are considered to be the same thing at this point) + /// + /// the scope to use + IRegister Scope(TScope scope); + + /// + /// direct access to the IoC's registration, Recommended for the more advanced setup's + /// + /// ioc's registration + IRegister Configure(Action> cfg); + } +} \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/RegisterBase.cs b/src/Boxes.Integration/ContainerSetup/RegisterBase.cs new file mode 100644 index 0000000..6fe8630 --- /dev/null +++ b/src/Boxes.Integration/ContainerSetup/RegisterBase.cs @@ -0,0 +1,77 @@ +namespace Boxes.Integration.ContainerSetup +{ + using System; + using System.Collections.Generic; + + public abstract class RegisterBase : IRegister + { + protected RegistrationMeta _meta = new RegistrationMeta(); + + public RegistrationMeta RegistrationMeta { get { return _meta; } } + + public virtual IRegister Where(Predicate where) + { + _meta.Where += where; + return this; + } + + public IRegister AssociateWith(Contracts contracts) + { + switch (contracts) + { + case Contracts.AllInterfaces: + _meta.With = type => type.AllInterfaces(); + break; + case Contracts.FirstInterface: + _meta.With = type => new[] { (type.FirstInterface() ?? type) }; + break; + case Contracts.SelfOnly: + _meta.With = type => new[] { type }; + break; + case Contracts.SelfAndAllInterfaces: + _meta.With = type => type.SelfAndAllInterfaces(); + break; + default: + throw new ArgumentOutOfRangeException("contracts"); + } + return this; + } + + public IRegister AssociateWith(Func> contracts) + { + _meta.With = contracts; + return this; + } + + public IRegister AssociateWith(IEnumerable contracts) + { + _meta.With = type => contracts; + return this; + } + + + public IRegister Ctor(Func factoryMethod) + { + _meta.FactoryMethod = factoryMethod; + return this; + } + + public IRegister LifeStyle(TScope lifeStyle) + { + _meta.LifeStyle = lifeStyle; + return this; + } + + public IRegister Scope(TScope scope) + { + _meta.LifeStyle = scope; + return this; + } + + public IRegister Configure(Action> cfg) + { + _meta.Configurations.Add(o => cfg((RegisterContext)o)); + return this; + } + } +} \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/RegisterContext.cs b/src/Boxes.Integration/ContainerSetup/RegisterContext.cs new file mode 100644 index 0000000..abb3ad8 --- /dev/null +++ b/src/Boxes.Integration/ContainerSetup/RegisterContext.cs @@ -0,0 +1,22 @@ +namespace Boxes.Integration.ContainerSetup +{ + using System; + + /// + /// a register context holds all the information required for someone to have complete control + /// over a single types registration. + /// + /// the underlying IoC registration type + public class RegisterContext + { + /// + /// the configuration of the underlying IoC registration + /// + public TConfiguration Configuration { get; set; } + + /// + /// the type the configuration is for + /// + public Type Type { get; set; } + } +} \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/Registration.cs b/src/Boxes.Integration/ContainerSetup/Registration.cs index ab4fa50..e530da3 100644 --- a/src/Boxes.Integration/ContainerSetup/Registration.cs +++ b/src/Boxes.Integration/ContainerSetup/Registration.cs @@ -16,29 +16,33 @@ namespace Boxes.Integration.ContainerSetup using System; using System.Collections.Generic; - public class Registration + /// + /// This class provides a mechanism to setup the registration of types with the underlying IoC. + /// + [Obsolete("Use Register, this will be removed, very soon")] + public class Registration : IRegister { - public Registration () + public Registration() { RegistrationMeta = new RegistrationMeta(); } - internal RegistrationMeta RegistrationMeta { get; private set; } + public RegistrationMeta RegistrationMeta { get; private set; } - public Registration RegisterWith(RegisterWith with) + public Registration RegisterWith(Contracts with) { switch (with) { - case ContainerSetup.RegisterWith.AllInterfaces: + case Contracts.AllInterfaces: RegistrationMeta.With = type => type.AllInterfaces(); break; - case ContainerSetup.RegisterWith.FirstInterface: + case Contracts.FirstInterface: RegistrationMeta.With = type => new[] { (type.FirstInterface() ?? type) }; break; - case ContainerSetup.RegisterWith.SelfOnly: + case Contracts.SelfOnly: RegistrationMeta.With = type => new[] { type }; break; - case ContainerSetup.RegisterWith.SelfAndAllInterfaces: + case Contracts.SelfAndAllInterfaces: RegistrationMeta.With = type => type.SelfAndAllInterfaces(); break; default: @@ -73,15 +77,20 @@ public Registration Ctor(Func factoryMethod) public Registration LifeStyle() { - RegistrationMeta.LifeStyle = typeof (TLifeStyle); + LifeStyle(typeof (TLifeStyle)); return this; } - public Registration Configure(Action cfg) + public Registration LifeStyle(object lifeStyle) { - RegistrationMeta.Configuraitions.Add(o => cfg((TConfiguration)o)); + RegistrationMeta.LifeStyle = lifeStyle; return this; } + public Registration Configure(Action cfg) + { + RegistrationMeta.Configurations.Add(o => cfg((TConfiguration)o)); + return this; + } } } \ No newline at end of file diff --git a/src/Boxes.Integration/ContainerSetup/RegistrationMeta.cs b/src/Boxes.Integration/ContainerSetup/RegistrationMeta.cs index a8b5db9..8a392e8 100644 --- a/src/Boxes.Integration/ContainerSetup/RegistrationMeta.cs +++ b/src/Boxes.Integration/ContainerSetup/RegistrationMeta.cs @@ -16,17 +16,40 @@ namespace Boxes.Integration.ContainerSetup using System; using System.Collections.Generic; + /// + /// stores information about the registration, this will be used to create a boxes task + /// public class RegistrationMeta { public RegistrationMeta() { - Configuraitions = new List>(); + Configurations = new List>(); } + /// + /// filter to apply + /// public Predicate Where { get; set; } + + /// + /// what to register it as + /// public Func> With { get; set; } - public Func FactoryMethod { get; set; } - public Type LifeStyle { get; set; } - public List> Configuraitions { get; private set; } + + /// + /// use custom ctor + /// + [Obsolete("this is being removed, the use of Configurations will allow for direct access to the registration")] + public object FactoryMethod { get; set; } + + /// + /// the scope of the types which this registration is for + /// + public object LifeStyle { get; set; } + + /// + /// a list of configurations to apply + /// + public List> Configurations { get; private set; } } } \ No newline at end of file diff --git a/src/Boxes.Integration/Setup/BoxesIntergrationSetup.cs b/src/Boxes.Integration/Setup/BoxesIntergrationSetup.cs index 72908a4..91b77dd 100644 --- a/src/Boxes.Integration/Setup/BoxesIntergrationSetup.cs +++ b/src/Boxes.Integration/Setup/BoxesIntergrationSetup.cs @@ -16,9 +16,6 @@ namespace Boxes.Integration.Setup using Boxes.Tasks; using Process; - /// - /// - /// public class BoxesIntergrationSetup : IBoxesIntegrationSetup { private readonly BoxesSetup _setup;