You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
Building a robust and reusable UI framework on top of Razor Components requires a more extensible system for processing CSHTML markup.
For example, I would like to build a component framework that utilizes the equivalent of UWP DependencyProperty's and data binding to support an MVVM pattern. I can get quite far (and already have) without modifying the core code and I'm NOT asking the team to implement this as part of Components.
However, I am stuck at a point where to support an elegant syntax, I would need to change the way parameter attributes are assigned to actual component instances.
For example, in CSHTML I would like to say something like:
This really cannot be done with the current framework without sacrificing the type safety of MyProperty as discussed below.
Describe the solution you'd like
I propose a new interface that would let us create custom mechanisms for assigning parameter values to component instances. You basically already have this with the IPropertySetter interface. I would expose this idea and make it more extensible, as such:
public interface IComponentMarkupExtension
{
void AssignValue(object target, string parameterName);
}
In the foreach loop in ParameterCollectionExtensions.SetParameterProperties, what I would do is:
if (parameter.Value is IComponentMarkupExtension markupExt)
markupExt.AssignValue(target, parameterName);
else
writerWithIndex.SetValue(target, parameter.Value);
Unless I'm missing something that would be the extent of the changes necessary to the core code. The rest would be handled at the application or component library level. For example, I would define my own Binding class as something like this (most implementation omitted):
public class Binding : IComponentMarkupExtension
{
public static Binding Create(string path, object source = null)
{
return new Binding(path: path, source: source);
}
public void AssignValue(object target, string parameterName)
{
BindingOperations.Bind(target, parameterName, this);
}
}
Accordingly, when I write <MyComponent MyProperty=@Binding.Create("MyViewModelProperty")/>
in markup, rather than try to assign a Binding instance to MyProperty, which would cause a type violation, my custom IMarkupExtension will invoke my own BindingOperations.Bind method instead.
I'm sure there are other potential uses for this that I haven't thought of, though robust data binding with an elegant syntax and without sacrificing type safety is really my most important objective here.
Describe alternatives you've considered
Until now I've been declaring property parameter types as dynamic. In each setter, a SetValue method is called that checks for whether the value is a markup extension. I do not like this approach however because it sacrifices type safety and can easily lead to runtime errors. This also doesn't work when the property type needs to be a RenderFragment because dynamic cannot be used for delegate types.
The text was updated successfully, but these errors were encountered:
Eilon
added
the
area-mvc
Includes: MVC, Actions and Controllers, Localization, CORS, most templates
label
Feb 25, 2019
Is your feature request related to a problem? Please describe.
Building a robust and reusable UI framework on top of Razor Components requires a more extensible system for processing CSHTML markup.
For example, I would like to build a component framework that utilizes the equivalent of UWP
DependencyProperty
's and data binding to support an MVVM pattern. I can get quite far (and already have) without modifying the core code and I'm NOT asking the team to implement this as part of Components.However, I am stuck at a point where to support an elegant syntax, I would need to change the way parameter attributes are assigned to actual component instances.
For example, in CSHTML I would like to say something like:
<MyComponent MyProperty=@Binding.Create("MyViewModelProperty")/>
This really cannot be done with the current framework without sacrificing the type safety of
MyProperty
as discussed below.Describe the solution you'd like
I propose a new interface that would let us create custom mechanisms for assigning parameter values to component instances. You basically already have this with the
IPropertySetter
interface. I would expose this idea and make it more extensible, as such:In the
foreach
loop inParameterCollectionExtensions.SetParameterProperties
, what I would do is:Unless I'm missing something that would be the extent of the changes necessary to the core code. The rest would be handled at the application or component library level. For example, I would define my own
Binding
class as something like this (most implementation omitted):Accordingly, when I write
<MyComponent MyProperty=@Binding.Create("MyViewModelProperty")/>
in markup, rather than try to assign a
Binding
instance toMyProperty
, which would cause a type violation, my customIMarkupExtension
will invoke my ownBindingOperations.Bind
method instead.I'm sure there are other potential uses for this that I haven't thought of, though robust data binding with an elegant syntax and without sacrificing type safety is really my most important objective here.
Describe alternatives you've considered
Until now I've been declaring property parameter types as
dynamic
. In each setter, aSetValue
method is called that checks for whether the value is a markup extension. I do not like this approach however because it sacrifices type safety and can easily lead to runtime errors. This also doesn't work when the property type needs to be aRenderFragment
becausedynamic
cannot be used for delegate types.The text was updated successfully, but these errors were encountered: