Skip to content

Commit

Permalink
A start of the API refactoring (Breaking changes)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dbones committed Jun 9, 2013
1 parent ba5c8fa commit cb6960e
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 29 deletions.
5 changes: 4 additions & 1 deletion src/Boxes.Integration/Boxes.Integration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ContainerSetup\IRegister.cs" />
<Compile Include="ContainerSetup\Register.cs" />
<Compile Include="ContainerSetup\RegisterContext.cs" />
<Compile Include="ContainerSetup\TypeExtensions.cs" />
<Compile Include="Process\TopologicalProcessOrder.cs" />
<Compile Include="Process\TopologicalSortExtensions.cs" />
Expand All @@ -70,7 +73,7 @@
<Compile Include="LoaderProxy.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tasks\RunOnceBoxesTask.cs" />
<Compile Include="ContainerSetup\RegisterWith.cs" />
<Compile Include="ContainerSetup\Contracts.cs" />
<Compile Include="ContainerSetup\Registration.cs" />
<Compile Include="ContainerSetup\RegistrationMeta.cs" />
<Compile Include="Tasks\SetupPackageTask.cs" />
Expand Down
7 changes: 7 additions & 0 deletions src/Boxes.Integration/BoxesWrapperBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,16 @@ public abstract class BoxesWrapperBase<TContainer> : 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.

/// <summary>
/// the main process line, add tasks to this, and they will be executed
/// in the order defined by <see cref="IProcessOrder"/>
Expand Down Expand Up @@ -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<Package> filteredPackages =
_setup.GlobalPackagesFilter == null
Expand Down
13 changes: 7 additions & 6 deletions src/Boxes.Integration/ContainerSetup/BoxesContainerSetupBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@ public abstract class BoxesContainerSetupBase : IBoxesContainerSetup

public abstract void RegisterLifeStyle<TLifeStyle, TInterface>();

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<Type> registrationTask)
public void AddRegistration(IRegister registration)
{
_registraionTasks.Add(registrationTask);
var task = CreateRegisterTask(registration.RegistrationMeta);
_registraionTasks.Add(task);
}

protected abstract IBoxesTask<Type> CreateRegisterTask(RegistrationMeta registration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
// limitations under the License.
namespace Boxes.Integration.ContainerSetup
{
using System;

/// <summary>
/// Register with which services
/// Register with which service contracts
/// </summary>
public enum RegisterWith
public enum Contracts
{
/// <summary>
/// All the interfaces
Expand All @@ -38,4 +40,10 @@ public enum RegisterWith
/// </summary>
SelfAndAllInterfaces
}

[Obsolete("Use Contracts", true)]
public enum RegisterWith
{

}
}
11 changes: 9 additions & 2 deletions src/Boxes.Integration/ContainerSetup/IBoxesContainerSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,20 @@ public interface IBoxesContainerSetup
/// </summary>
/// <typeparam name="TLifeStyle">The lifestyle manager to use</typeparam>
/// <typeparam name="TInterface">The Dependency interface to register with the lifecycle</typeparam>
[Obsolete("use the other overload")]
[Obsolete("use AddRegistration", true)]
void RegisterLifeStyle<TLifeStyle, TInterface>();

/// <summary>
/// Register a type (can be as simple as does it implement a Dependency or to apply a filter)
/// </summary>
/// <param name="registration">The registration with details on how setup the IoC with the types which match the where clause</param>
void RegisterLifeStyle(Registration registration);
[Obsolete("use AddRegistration")]
void RegisterLifeStyle(IRegister registration);

/// <summary>
/// Register a type (can be as simple as does it implement a Dependency or to apply a filter)
/// </summary>
/// <param name="registration">The registration with details on how setup the IoC with the types which match the where clause</param>
void AddRegistration(IRegister registration);
}
}
74 changes: 74 additions & 0 deletions src/Boxes.Integration/ContainerSetup/IRegister.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace Boxes.Integration.ContainerSetup
{
using System;
using System.Collections.Generic;

/// <summary>
/// This class provides a mechanism to setup the registration of types with the underlying IoC.
/// </summary>
public interface IRegister
{
/// <summary>
/// meta information about the registration
/// </summary>
RegistrationMeta RegistrationMeta { get; }
}

/// <summary>
/// This class provides a mechanism to setup the registration of types with the underlying IoC.
/// </summary>
/// <typeparam name="TScope">The signature for the scope/lifestyle</typeparam>
/// <typeparam name="TConfiguration">the IoC direct configuration for the current registration</typeparam>
public interface IRegister<TScope, TConfiguration> : IRegister
{
/// <summary>
/// apply a filter (pattern) to find which types this registration will apply too
/// </summary>
/// <param name="where">the pattern to find the types this registration applies too</param>
IRegister<TScope, TConfiguration> Where(Predicate<Type> where);

/// <summary>
/// which contracts to associate the current type with
/// </summary>
/// <param name="contracts">select the appropriate contracts to register this class with</param>
IRegister<TScope, TConfiguration> AssociateWith(Contracts contracts);

/// <summary>
/// which contracts to associate the current type with
/// </summary>
/// <param name="contracts">provide a list of contracts to associate the current type with</param>
IRegister<TScope, TConfiguration> AssociateWith(Func<Type, IEnumerable<Type>> contracts);

/// <summary>
/// which contracts to associate the current type with
/// </summary>
/// <param name="contracts">provide a list of contracts to associate the current type with</param>
IRegister<TScope, TConfiguration> AssociateWith(IEnumerable<Type> contracts);

/// <summary>
/// supply a ctor to use, apply this in the Configure Method, as this will allow direct access
/// to the actual IoC's registration
/// </summary>
/// <param name="factoryMethod">the ctor to use</param>
[Obsolete("not all IoC's support this", true)]
IRegister<TScope, TConfiguration> Ctor(Func<object> factoryMethod);

/// <summary>
/// the life style of the type (scope and lifestyle are considered to be the same thing at this point)
/// </summary>
/// <param name="lifeStyle">the life style to use</param>
IRegister<TScope, TConfiguration> LifeStyle(TScope lifeStyle);

/// <summary>
/// the scope of the type (scope and lifestyle are considered to be the same thing at this point)
/// </summary>
/// <param name="scope">the scope to use</param>
IRegister<TScope, TConfiguration> Scope(TScope scope);

/// <summary>
/// direct access to the IoC's registration, Recommended for the more advanced setup's
/// </summary>
/// <param name="cfg">ioc's registration</param>
IRegister<TScope, TConfiguration> Configure(Action<RegisterContext<TConfiguration>> cfg);
}
}
77 changes: 77 additions & 0 deletions src/Boxes.Integration/ContainerSetup/RegisterBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
namespace Boxes.Integration.ContainerSetup
{
using System;
using System.Collections.Generic;

public abstract class RegisterBase<TScope, TConfiguration> : IRegister<TScope, TConfiguration>
{
protected RegistrationMeta _meta = new RegistrationMeta();

public RegistrationMeta RegistrationMeta { get { return _meta; } }

public virtual IRegister<TScope, TConfiguration> Where(Predicate<Type> where)
{
_meta.Where += where;
return this;
}

public IRegister<TScope, TConfiguration> 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<TScope, TConfiguration> AssociateWith(Func<Type, IEnumerable<Type>> contracts)
{
_meta.With = contracts;
return this;
}

public IRegister<TScope, TConfiguration> AssociateWith(IEnumerable<Type> contracts)
{
_meta.With = type => contracts;
return this;
}


public IRegister<TScope, TConfiguration> Ctor(Func<object> factoryMethod)
{
_meta.FactoryMethod = factoryMethod;
return this;
}

public IRegister<TScope, TConfiguration> LifeStyle(TScope lifeStyle)
{
_meta.LifeStyle = lifeStyle;
return this;
}

public IRegister<TScope, TConfiguration> Scope(TScope scope)
{
_meta.LifeStyle = scope;
return this;
}

public IRegister<TScope, TConfiguration> Configure(Action<RegisterContext<TConfiguration>> cfg)
{
_meta.Configurations.Add(o => cfg((RegisterContext<TConfiguration>)o));
return this;
}
}
}
22 changes: 22 additions & 0 deletions src/Boxes.Integration/ContainerSetup/RegisterContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Boxes.Integration.ContainerSetup
{
using System;

/// <summary>
/// a register context holds all the information required for someone to have complete control
/// over a single types registration.
/// </summary>
/// <typeparam name="TConfiguration">the underlying IoC registration type</typeparam>
public class RegisterContext<TConfiguration>
{
/// <summary>
/// the configuration of the underlying IoC registration
/// </summary>
public TConfiguration Configuration { get; set; }

/// <summary>
/// the type the configuration is for
/// </summary>
public Type Type { get; set; }
}
}
31 changes: 20 additions & 11 deletions src/Boxes.Integration/ContainerSetup/Registration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,33 @@ namespace Boxes.Integration.ContainerSetup
using System;
using System.Collections.Generic;

public class Registration
/// <summary>
/// This class provides a mechanism to setup the registration of types with the underlying IoC.
/// </summary>
[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:
Expand Down Expand Up @@ -73,15 +77,20 @@ public Registration Ctor(Func<object> factoryMethod)

public Registration LifeStyle<TLifeStyle>()
{
RegistrationMeta.LifeStyle = typeof (TLifeStyle);
LifeStyle(typeof (TLifeStyle));
return this;
}

public Registration Configure<TConfiguration>(Action<TConfiguration> cfg)
public Registration LifeStyle(object lifeStyle)
{
RegistrationMeta.Configuraitions.Add(o => cfg((TConfiguration)o));
RegistrationMeta.LifeStyle = lifeStyle;
return this;
}

public Registration Configure<TConfiguration>(Action<TConfiguration> cfg)
{
RegistrationMeta.Configurations.Add(o => cfg((TConfiguration)o));
return this;
}
}
}
Loading

0 comments on commit cb6960e

Please sign in to comment.