1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.XamlIntegration
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime;
using System.Windows.Markup;
using System.Xaml;
abstract class FuncFactory
{
public static Func<object> CreateFunc(XamlReader reader, Type returnType)
{
FuncFactory factory = CreateFactory(null, reader, returnType);
return factory.GetFunc();
}
public static Func<T> CreateFunc<T>(XamlReader reader) where T : class
{
FuncFactory<T> factory = new FuncFactory<T>(null, reader);
return factory.GetTypedFunc();
}
internal IList<NamespaceDeclaration> ParentNamespaces
{
get;
set;
}
internal XamlNodeList Nodes
{
get;
set;
}
// Back-compat switch: we don't want to copy parent settings on Activity/DynamicActivity
internal bool IgnoreParentSettings
{
get;
set;
}
internal abstract Func<object> GetFunc();
internal static FuncFactory CreateFactory(XamlReader xamlReader, IServiceProvider context)
{
IXamlObjectWriterFactory objectWriterFactory = context.GetService(typeof(IXamlObjectWriterFactory)) as IXamlObjectWriterFactory;
IProvideValueTarget provideValueService = context.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
Type propertyType = null;
//
// IProvideValueTarget.TargetProperty can return DP, Attached Property or MemberInfo for clr property
// In this case it should always be a regular clr property here - we are always targeting Activity.Body.
PropertyInfo propertyInfo = provideValueService.TargetProperty as PropertyInfo;
if (propertyInfo != null)
{
propertyType = propertyInfo.PropertyType;
}
FuncFactory funcFactory = CreateFactory(objectWriterFactory, xamlReader, propertyType.GetGenericArguments());
return funcFactory;
}
// Back-compat workaround: returnType should only be a single value. But in 4.0 we didn't
// validate this; we just passed the array in to MakeGenericType, which would throw if there
// were multiple values. To preserve the same exception, we allow passing in an array here.
static FuncFactory CreateFactory(IXamlObjectWriterFactory objectWriterFactory, XamlReader xamlReader, params Type[] returnType)
{
Type closedType = typeof(FuncFactory<>).MakeGenericType(returnType);
return (FuncFactory)Activator.CreateInstance(closedType, objectWriterFactory, xamlReader);
}
}
class FuncFactory<T> : FuncFactory where T : class
{
IXamlObjectWriterFactory objectWriterFactory;
public FuncFactory(IXamlObjectWriterFactory objectWriterFactory, XamlReader reader)
{
this.objectWriterFactory = objectWriterFactory;
this.Nodes = new XamlNodeList(reader.SchemaContext);
XamlServices.Transform(reader, this.Nodes.Writer);
}
internal T Evaluate()
{
XamlObjectWriter writer = GetWriter();
XamlServices.Transform(this.Nodes.GetReader(), writer);
return (T)writer.Result;
}
internal override Func<object> GetFunc()
{
return (Func<T>)Evaluate;
}
internal Func<T> GetTypedFunc()
{
return Evaluate;
}
XamlObjectWriter GetWriter()
{
if (this.objectWriterFactory != null)
{
return this.objectWriterFactory.GetXamlObjectWriter(GetObjectWriterSettings());
}
else
{
return new XamlObjectWriter(this.Nodes.Writer.SchemaContext);
}
}
XamlObjectWriterSettings GetObjectWriterSettings()
{
if (IgnoreParentSettings)
{
return new XamlObjectWriterSettings();
}
XamlObjectWriterSettings result = new XamlObjectWriterSettings(this.objectWriterFactory.GetParentSettings());
// The delegate settings are already stripped by XOW. Some other settings don't make sense to copy.
result.ExternalNameScope = null;
result.RegisterNamesOnExternalNamescope = false;
result.RootObjectInstance = null;
result.SkipProvideValueOnRoot = false;
return result;
}
}
}
|