Skip to content
This repository has been archived by the owner on Apr 2, 2020. It is now read-only.

Commit

Permalink
Abstract package protocol handling a little
Browse files Browse the repository at this point in the history
This isn't as abstracted as I would like, especially since there's still a huge number of out parameters coming out of the IPackageLookup interface, but at least this moves us somewhat away from a giant hard-coded if statement.
  • Loading branch information
hach-que committed Dec 24, 2015
1 parent 8a02651 commit 2971a4c
Show file tree
Hide file tree
Showing 26 changed files with 741 additions and 310 deletions.
11 changes: 11 additions & 0 deletions Build/Projects/Protobuild.Internal.definition
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,18 @@
<Compile Include="Packages\PackageLookup\IPackageLookup.cs" />
<Compile Include="Packages\PackageLookup\PackageLookup.cs" />
<Compile Include="Packages\PackageManager.cs" />
<Compile Include="Packages\PackageMetadata\FolderPackageMetadata.cs" />
<Compile Include="Packages\PackageMetadata\GitPackageMetadata.cs" />
<Compile Include="Packages\PackageMetadata\IPackageMetadata.cs" />
<Compile Include="Packages\PackageMetadata\NuGetPackageMetadata.cs" />
<Compile Include="Packages\PackageMetadata\ProtobuildPackageMetadata.cs" />
<Compile Include="Packages\PackageNameLookup.cs" />
<Compile Include="Packages\PackageProtocol\GitPackageProtocol.cs" />
<Compile Include="Packages\PackageProtocol\IPackageProtocol.cs" />
<Compile Include="Packages\PackageProtocol\LocalTemplateGitPackageProtocol.cs" />
<Compile Include="Packages\PackageProtocol\LocalTemplatePackageProtocol.cs" />
<Compile Include="Packages\PackageProtocol\NuGetPackageProtocol.cs" />
<Compile Include="Packages\PackageProtocol\ProtobuildPackageProtocol.cs" />
<Compile Include="Packages\PackageRedirector\IPackageRedirector.cs" />
<Compile Include="Packages\PackageRedirector\PackageRedirector.cs" />
<Compile Include="Packages\PackageRetrieval\IPackageRetrieval.cs" />
Expand Down
1 change: 1 addition & 0 deletions Build/Projects/Protobuild.UnitTests.definition
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<Files>
<Compile Include="FeatureManagerTests.cs" />
<Compile Include="ModuleInfoLoadTests.cs" />
<Compile Include="PackageLookupTests.cs" />
<Compile Include="PackageRefTests.cs" />
<Compile Include="PathUtilsTests.cs" />
<Compile Include="ServiceResolutionTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Module>
<?xml version="1.0" encoding="utf-8"?>
<ModuleInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Game</Name>
<DefaultAction>resync</DefaultAction>
<GenerateNuGetRepositories>true</GenerateNuGetRepositories>
</Module>
<DisableSynchronisation xsi:nil="true" />
<ModuleAssemblies />
</ModuleInfo>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Module>
<?xml version="1.0" encoding="utf-8"?>
<ModuleInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Cocos2DXNA</Name>
<DefaultAction>resync</DefaultAction>
<GenerateNuGetRepositories>true</GenerateNuGetRepositories>
</Module>
<DisableSynchronisation xsi:nil="true" />
<ModuleAssemblies />
</ModuleInfo>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Module>
<?xml version="1.0" encoding="utf-8"?>
<ModuleInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Game</Name>
<DefaultAction>resync</DefaultAction>
<GenerateNuGetRepositories>true</GenerateNuGetRepositories>
</Module>
<DisableSynchronisation xsi:nil="true" />
<ModuleAssemblies />
</ModuleInfo>
96 changes: 68 additions & 28 deletions Protobuild.Internal/DI/LightweightKernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Protobuild
{
public class LightweightKernel
{
private Dictionary<Type, Type> m_Bindings = new Dictionary<Type, Type>();
private Dictionary<Type, List<Type>> m_Bindings = new Dictionary<Type, List<Type>>();

private Dictionary<string, Type> m_NamedBindings = new Dictionary<string, Type>();

Expand All @@ -32,14 +32,22 @@ public void BindAll()

public void Bind<TInterface, TImplementation>() where TImplementation : TInterface
{
this.m_Bindings.Add(typeof(TInterface), typeof(TImplementation));
this.m_KeepInstance.Add(typeof(TInterface), false);
if (!this.m_Bindings.ContainsKey(typeof (TInterface)))
{
this.m_Bindings.Add(typeof(TInterface), new List<Type>());
}
this.m_Bindings[typeof(TInterface)].Add(typeof(TImplementation));
this.m_KeepInstance[typeof(TInterface)] = false;
}

public void BindAndKeepInstance<TInterface, TImplementation>() where TImplementation : TInterface
{
this.m_Bindings.Add(typeof(TInterface), typeof(TImplementation));
this.m_KeepInstance.Add(typeof(TInterface), true);
if (!this.m_Bindings.ContainsKey(typeof(TInterface)))
{
this.m_Bindings.Add(typeof(TInterface), new List<Type>());
}
this.m_Bindings[typeof(TInterface)].Add(typeof(TImplementation));
this.m_KeepInstance[typeof(TInterface)] = true;
}

public T Get<T>()
Expand All @@ -64,6 +72,13 @@ private object Get(Type original, List<Type> seen)
return this;
}

var isArray = false;
if (original.IsArray)
{
original = original.GetElementType();
isArray = true;
}

if (seen.Contains(original))
{
throw new InvalidOperationException(
Expand All @@ -74,7 +89,7 @@ private object Get(Type original, List<Type> seen)

seen.Add(original);

Type actual;
Type[] actuals;

if (this.m_Bindings.ContainsKey(original))
{
Expand All @@ -86,48 +101,73 @@ private object Get(Type original, List<Type> seen)
}
}

actual = this.m_Bindings[original];
actuals = this.m_Bindings[original].ToArray();
}
else
{
actual = original;
actuals = new [] { original };
}

if (actual.IsInterface)
if (actuals.All(x => x.IsInterface))
{
throw new InvalidOperationException("Resolved type " + actual.FullName + " was an interface; make sure there is a binding present!");
throw new InvalidOperationException("Resolved types " + actuals.Select(x => x.FullName).Aggregate((a, b) => a + ", " + b) + " were all interfaces; make sure there is a binding present!");
}

var constructor = actual.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault();
actuals = actuals.Where(x => !x.IsInterface).ToArray();

if (constructor == null)
var instances = new List<object>();
foreach (var actual in actuals)
{
throw new InvalidOperationException("Type " + actual.FullName + " does not have a public constructor.");
}
var constructor = actual.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault();

var parameters = constructor.GetParameters();
if (constructor == null)
{
throw new InvalidOperationException("Type " + actual.FullName + " does not have a public constructor.");
}

var resolved = new object[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
var parameterType = parameters[i].ParameterType;
resolved[i] = this.Get(parameterType, seen.ToList());
}
var parameters = constructor.GetParameters();

var instance = constructor.Invoke(resolved);
var resolved = new object[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
var parameterType = parameters[i].ParameterType;
resolved[i] = this.Get(parameterType, seen.ToList());
}

if (this.m_Bindings.ContainsKey(original))
{
if (this.m_KeepInstance[original])
var instance = constructor.Invoke(resolved);

if (this.m_Bindings.ContainsKey(original))
{
if (!this.m_Instances.ContainsKey(original))
if (this.m_KeepInstance[original])
{
this.m_Instances[original] = instance;
if (!this.m_Instances.ContainsKey(original))
{
this.m_Instances[original] = instance;
}
}
}

instances.Add(instance);
}

if (isArray)
{
var arrayInstance = (Array)Activator.CreateInstance(original.MakeArrayType(), instances.Count);
for (var i = 0; i < instances.Count; i++)
{
arrayInstance.SetValue(instances[i], i);
}
return arrayInstance;
}
else
{
if (instances.Count > 1)
{
throw new InvalidOperationException("More than one binding for " + original.FullName + " and non-array requested.");
}

return instance;
return instances.First();
}
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion Protobuild.Internal/DI/LightweightKernelModule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Protobuild
using Protobuild.Internal;

namespace Protobuild
{
public static class LightweightKernelModule
{
Expand Down Expand Up @@ -72,6 +74,12 @@ public static void BindPackages(this LightweightKernel kernel)
kernel.Bind<IPackageUrlParser, PackageUrlParser>();
kernel.Bind<IKnownToolProvider, KnownToolProvider>();
kernel.Bind<IPackageNameLookup, PackageNameLookup>();

kernel.Bind<IPackageProtocol, GitPackageProtocol>();
kernel.Bind<IPackageProtocol, LocalTemplatePackageProtocol>();
kernel.Bind<IPackageProtocol, LocalTemplateGitPackageProtocol>();
kernel.Bind<IPackageProtocol, NuGetPackageProtocol>();
kernel.Bind<IPackageProtocol, ProtobuildPackageProtocol>();
}

public static void BindAutomatedBuild(this LightweightKernel kernel)
Expand Down
11 changes: 1 addition & 10 deletions Protobuild.Internal/Packages/PackageLookup/IPackageLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,7 @@ namespace Protobuild
{
public interface IPackageLookup
{
void Lookup(
string uri,
string platform,
bool preferCacheLookup,
out string sourceUri,
out string type,
out Dictionary<string, string> downloadMap,
out Dictionary<string, string> archiveTypeMap,
out Dictionary<string, string> resolvedHash,
out IPackageTransformer transformer);
void Lookup(string uri, string platform, bool preferCacheLookup, out string sourceUri, out string sourceFormat, out string type, out Dictionary<string, string> downloadMap, out Dictionary<string, string> archiveTypeMap, out Dictionary<string, string> resolvedHash, out IPackageTransformer transformer);
}
}

Loading

0 comments on commit 2971a4c

Please sign in to comment.