Skip to content

MarkupExtension use interface instead of abstract class #306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;

namespace System.Windows.Markup
{
/// <summary>
/// Base interface for all Xaml markup extensions.
/// </summary>
public interface IMarkupExtension
{
/// <summary>
/// Return an object that should be set on the targetObject's targetProperty
/// for this markup extension.
/// </summary>
/// <param name="serviceProvider">Object that can provide services for the markup extension.</param>
/// <returns>
/// The object to set on this property.
/// </returns>
object ProvideValue(IServiceProvider serviceProvider);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace System.Windows.Markup
/// be instantiated.
/// </summary>
[TypeForwardedFrom("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
public abstract class MarkupExtension
public abstract class MarkupExtension : IMarkupExtension
{
/// <summary>
/// Return an object that should be set on the targetObject's targetProperty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ namespace System.Windows.Markup
public class XamlSetMarkupExtensionEventArgs : XamlSetValueEventArgs
{
public XamlSetMarkupExtensionEventArgs(XamlMember member,
MarkupExtension value, IServiceProvider serviceProvider) :
IMarkupExtension value, IServiceProvider serviceProvider) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change

base(member, value)
{
ServiceProvider = serviceProvider;
}

public MarkupExtension MarkupExtension { get { return Value as MarkupExtension; } }
public IMarkupExtension MarkupExtension { get { return Value as IMarkupExtension; } }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change.
Perhaps injecting a base class between this class and XamlSetValueEventArgs that adds the interface version, and leave XamlSetMarkupExtensionEventArgs alone (apart from now inheriting from the intermediate class).

public IServiceProvider ServiceProvider { get; private set; }

internal XamlSetMarkupExtensionEventArgs(XamlMember member,
MarkupExtension value, IServiceProvider serviceProvider, object targetObject)
IMarkupExtension value, IServiceProvider serviceProvider, object targetObject)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change

: this(member, value, serviceProvider)
{
TargetObject = targetObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ private List<AmbientPropertyValue> FindAmbientValues(IEnumerable<XamlType> ceili
// One last thing to check: If the object we are inside is a ME
// then we are inside a call to ProvideValue and we don't want to
// return a reference to ourselves to ourselves.
if (!(lowerFrame.Instance is XAML3.MarkupExtension))
if (!(lowerFrame.Instance is XAML3.IMarkupExtension))
{
returnAmbientValue = true;
value = lowerFrame.Instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ public override void WriteEndMember()
bool shouldSetValue = true;
if (value != null)
{
XAML3.MarkupExtension me = value as XAML3.MarkupExtension;
XAML3.IMarkupExtension me = value as XAML3.IMarkupExtension;
if (me != null)
{
_context.CurrentInstance = me;
Expand Down Expand Up @@ -1156,7 +1156,7 @@ private void Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
object[] args = ctx.CurrentCtorArgs;
for (int i = 0; i < args.Length; i++)
{
XAML3.MarkupExtension me = args[i] as XAML3.MarkupExtension;
XAML3.IMarkupExtension me = args[i] as XAML3.IMarkupExtension;
if (me != null)
{
args[i] = Logic_PushAndPopAProvideValueStackFrame(ctx, XamlLanguage.PositionalParameters, me, false);
Expand Down Expand Up @@ -1216,7 +1216,7 @@ private void Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
// If UsableDuringInit, Assign to parent
// We don't want to assign MEs to the parent since we need to call ProvideValue on them
// which is handled in WriteEndObject
if (ctx.LiveDepth > 1 && !(inst is XAML3.MarkupExtension))
if (ctx.LiveDepth > 1 && !(inst is XAML3.IMarkupExtension))
{
if (ctx.LiveDepth > 1)
{
Expand Down Expand Up @@ -1565,7 +1565,7 @@ private void Logic_ApplyCurrentPreconstructionPropertyValues(ObjectWriterContext
// so don't call ProvideValue() now on directives here.
// (x:Key and x:Name need their own "saved spot" outside of PreconstructionPropertyValues)

XAML3.MarkupExtension me = value as XAML3.MarkupExtension;
XAML3.IMarkupExtension me = value as XAML3.IMarkupExtension;
if (me != null && !prop.IsDirective)
{
Logic_PushAndPopAProvideValueStackFrame(ctx, prop, me, true);
Expand All @@ -1578,7 +1578,7 @@ private void Logic_ApplyCurrentPreconstructionPropertyValues(ObjectWriterContext
}
}

private object Logic_PushAndPopAProvideValueStackFrame(ObjectWriterContext ctx, XamlMember prop, XAML3.MarkupExtension me, bool useIRME)
private object Logic_PushAndPopAProvideValueStackFrame(ObjectWriterContext ctx, XamlMember prop, XAML3.IMarkupExtension me, bool useIRME)
{
XamlMember savedProp = ctx.CurrentProperty;
ctx.CurrentProperty = prop;
Expand Down Expand Up @@ -1689,7 +1689,7 @@ private void Logic_AssignProvidedValue(ObjectWriterContext ctx)
private bool Logic_ProvideValue(ObjectWriterContext ctx)
{
object inst = ctx.CurrentInstance;
XAML3.MarkupExtension me = (XAML3.MarkupExtension)inst;
XAML3.IMarkupExtension me = (XAML3.IMarkupExtension)inst;
object parentInstance = ctx.ParentInstance;
XamlMember parentProperty = ctx.ParentProperty;

Expand Down Expand Up @@ -1806,7 +1806,7 @@ private void Logic_DoAssignmentToParentCollection(ObjectWriterContext ctx)
{
// If Value is a Markup Extention then check the collection item type
// if it can hold the ME then don't call ProvideValue().
XAML3.MarkupExtension me = value as XAML3.MarkupExtension;
XAML3.IMarkupExtension me = value as XAML3.IMarkupExtension;
if(me != null && !Logic_WillParentCollectionAdd(ctx, value.GetType(), true))
{
// We don't need to call Logic_ProvideValue() with the extra handler
Expand Down Expand Up @@ -2516,7 +2516,7 @@ private void ProcessNameFixup_Reparse(NameFixupToken token, bool nameResolutionI
break;
case FixupType.MarkupExtensionRerun:
// Logic_ProvideValue already ran the first time, no need to rerun it
value = Runtime.CallProvideValue((XAML3.MarkupExtension)owc.CurrentInstance, owc.ServiceProviderContext);
value = Runtime.CallProvideValue((XAML3.IMarkupExtension)owc.CurrentInstance, owc.ServiceProviderContext);
owc.CurrentInstance = value;
break;
case FixupType.PropertyValue:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ public override void InitializationGuard(XamlType xamlType, object obj, bool beg
}
}

public override object CallProvideValue(XAML3.MarkupExtension me, IServiceProvider serviceProvider)
public override object CallProvideValue(XAML3.IMarkupExtension me, IServiceProvider serviceProvider)
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public override void AddToDictionary(object collection, XamlType dictionaryType,
_transparentRuntime.AddToDictionary(collection, dictionaryType, value, valueXamlType, key);
}

public override object CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
public override object CallProvideValue(IMarkupExtension me, IServiceProvider serviceProvider)
{
// Once the ME is instantiated, invocation is always a public method call
return _transparentRuntime.CallProvideValue(me, serviceProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static class XamlLanguage
new Lazy<XamlType>(() => GetXamlType(typeof(List<Attribute>)));
// These aren't language built-ins, but we use them in schema
private static Lazy<XamlType> s_markupExtension =
new Lazy<XamlType>(() => GetXamlType(typeof(MarkupExtension)));
new Lazy<XamlType>(() => GetXamlType(typeof(IMarkupExtension)));
private static Lazy<XamlType> s_iNameScope =
new Lazy<XamlType>(() => GetXamlType(typeof(INameScope)));
private static Lazy<XamlType> s_iXmlSerializable =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ bool TryAddPositionalParameters(XamlType xamlType, MemberInfo member, ICollectio
context.Instance = null;
positionalParametersProperty.Children.Add(new ValueMarkupInfo { XamlNode = new XamlNode(XamlNodeType.Value, stringValue) });
}
else if ((converter != null && context.TryConvertToMarkupExtension(converter, ref meObject)) || meObject is MarkupExtension)
else if ((converter != null && context.TryConvertToMarkupExtension(converter, ref meObject)) || meObject is IMarkupExtension)
{
context.Instance = null;
objectInfo = ForObject(meObject, context);
Expand Down Expand Up @@ -2725,9 +2725,9 @@ public bool TryTypeConvertToString(TypeConverter converter, ref object value)
public bool TryConvertToMarkupExtension(TypeConverter converter, ref object value)
{
if (value == null) { return false; }
if (!Runtime.CanConvertTo(TypeDescriptorContext, converter, typeof(MarkupExtension))) { return false; }
if (!Runtime.CanConvertTo(TypeDescriptorContext, converter, typeof(IMarkupExtension))) { return false; }

value = ConvertTo<MarkupExtension>(converter, value);
value = ConvertTo<IMarkupExtension>(converter, value);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public object GetValue(object obj, XamlMember property)

abstract public void InitializationGuard(XamlType xamlType, object obj, bool begin);

abstract public object CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider);
abstract public object CallProvideValue(IMarkupExtension me, IServiceProvider serviceProvider);

abstract public ShouldSerializeResult ShouldSerialize(XamlMember member, object instance);

Expand Down