How to make an object factory?

Oct 5, 2010 at 12:39 PM

I created a tag / attribute as follow:

---

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DataViewAttribute : ExportAttribute
{
	public DataViewAttribute(Type t)
		: base("DataView")
	{
		DataType = t;
	}

	public Type DataType { get; set; }
}

---

I managed to find the item of interest with the following code (attempt at factory method)

--

public static object GetView(object data)
{
	if (data == null)
		return null;

	if (data is UIElement)
		return (UIElement)data;

	var tt = data.GetType();

	var id = new ImportDefinition(
		ef => ef.ContractName == "DataView" 
		, "DataView"
		, ImportCardinality.ZeroOrMore
		, false
		, false);
	var list = Container.GetExports(id);
	foreach (var item in list)
	{
		string target = (string)item.Metadata["ExportTypeIdentity"];
		var type = ((Type[])item.Metadata["DataType"])[0];
		if (type.IsAssignableFrom(tt))
		{
			//var result = Activator.CreateInstance(Type.GetType(target));
			var result = item.Value;
			var ui = result as FrameworkElement;
			if (ui != null)
			{
				ui.DataContext = data;
				Compose(ui);
				return ui;
			}
		}
	}

  return null;

 }


--

Unfortunately item.Value always return the same instance, whereas I need a new instance every time!

I tried Activator.CreateInstance(Type.GetType(target)) (commented out), unfortunately Type.GetType(target) returns null...

Any clues / tips?

Oct 5, 2010 at 1:04 PM

Found it!
I should enumerate the Catalog instead of the Container!

As in:

 

public static object GetView(object data)
{
	if (data == null)
		return null;

	if (data is UIElement)
		return (UIElement)data;

	var tt = data.GetType();

	var id = new ImportDefinition(
		ef => ef.ContractName == "DataView"
		, "DataView"
		, ImportCardinality.ZeroOrMore
		, false
		, false);
	var list2 = Catalog.GetExports(id);
	foreach (var item in list2)
	{
		string target = (string)item.Item2.Metadata["ExportTypeIdentity"];
		var type = ((Type[])item.Item2.Metadata["DataType"])[0];
		if (type.IsAssignableFrom(tt))
		{
			object result = item.Item1.CreatePart().GetExportedValue(item.Item2);
			var ui = result as FrameworkElement;
			if (ui != null)
			{
				ui.DataContext = data;
				Compose(ui);
				return ui;
			}
		}
	}
	return data;
}