Ich muss meiner Inhalts-Pipeline-Erweiterung erlauben, ein Muster zu verwenden, das einer Factory ähnelt. Ich beginne mit einem Wörterbuchtyp:Zugreifen auf einen Service über eine XNA-Inhalts-Pipeline-Erweiterung
public delegate T Mapper<T>(MapFactory<T> mf, XElement d);
public class MapFactory<T>
{
Dictionary<string, Mapper<T>> map = new Dictionary<string, Mapper<T>>();
public void Add(string s, Mapper<T> m)
{
map.Add(s, m);
}
public T Get(XElement xe)
{
if (xe == null) throw new ArgumentNullException(
"Invalid document");
var key = xe.Name.ToString();
if (!map.ContainsKey(key)) throw new ArgumentException(
key + " is not a valid key.");
return map[key](this, xe);
}
public IEnumerable<T> GetAll(XElement xe)
{
if (xe == null) throw new ArgumentNullException(
"Invalid document");
foreach (var e in xe.Elements())
{
var val = e.Name.ToString();
if (map.ContainsKey(val))
yield return map[val](this, e);
}
}
}
Hier ist eine Art von Objekt, das ich gespeichert werden soll:
public partial class TestContent
{
// Test type
public string title;
// Once test if true
public bool once;
// Parameters
public Dictionary<string, object> args;
public TestContent()
{
title = string.Empty;
args = new Dictionary<string, object>();
}
public TestContent(XElement xe)
{
title = xe.Name.ToString();
args = new Dictionary<string, object>();
xe.ParseAttribute("once", once);
}
}
XElement.ParseAttribute ist eine Erweiterung Methode, die funktioniert wie man erwarten könnte. Es gibt einen booleschen Wert zurück, der wahr ist, wenn er erfolgreich ist.
Das Problem ist, dass ich viele verschiedene Arten von Tests habe, von denen jede das Objekt in einer Weise füllt, die für den spezifischen Test einzigartig ist. Der Elementname ist der Schlüssel zum MapFactory-Wörterbuch. Diese Art von Test, obwohl atypisch, veranschaulicht mein Problem.
public class LogicTest : TestBase
{
string opkey;
List<TestBase> items;
public override bool Test(BehaviorArgs args)
{
if (items == null) return false;
if (items.Count == 0) return false;
bool result = items[0].Test(args);
for (int i = 1; i < items.Count; i++)
{
bool other = items[i].Test(args);
switch (opkey)
{
case "And":
result &= other;
if (!result) return false;
break;
case "Or":
result |= other;
if (result) return true;
break;
case "Xor":
result ^= other;
break;
case "Nand":
result = !(result & other);
break;
case "Nor":
result = !(result | other);
break;
default:
result = false;
break;
}
}
return result;
}
public static TestContent Build(MapFactory<TestContent> mf, XElement xe)
{
var result = new TestContent(xe);
string key = "Or";
xe.GetAttribute("op", key);
result.args.Add("key", key);
var names = mf.GetAll(xe).ToList();
if (names.Count() < 2) throw new ArgumentException(
"LogicTest requires at least two entries.");
result.args.Add("items", names);
return result;
}
}
Mein eigentlicher Code ist mehr beteiligt als die Fabrik zwei Wörterbücher hat, eine, die eine XElement in einen Inhaltstyp wird zu schreiben und ein andere durch den Leser verwendet, um die eigentlichen Spiel-Objekte zu erstellen.
Ich muss diese Fabriken in Code erstellen, da sie Zeichenfolgen Delegaten zuordnen. Ich habe einen Service, der mehrere dieser Fabriken enthält. Die Aufgabe besteht darin, diese Factory-Klassen einem Content-Prozessor zur Verfügung zu stellen. Weder der Prozessor selbst noch der Kontext, den er als Parameter verwendet, haben irgendwelche bekannten Hooks, um einen IServiceProvider oder ein Äquivalent anzuhängen.
Irgendwelche Ideen?