Revert "Adding support for activating view properties"
This reverts commit 21bb8cb9fb.
This commit is contained in:
parent
21bb8cb9fb
commit
3692cc7d83
|
|
@ -23,7 +23,6 @@
|
||||||
<Compile Include="Encodings.cs" />
|
<Compile Include="Encodings.cs" />
|
||||||
<Compile Include="NotNullArgument.cs" />
|
<Compile Include="NotNullArgument.cs" />
|
||||||
<Compile Include="PlatformHelper.cs" />
|
<Compile Include="PlatformHelper.cs" />
|
||||||
<Compile Include="PropertyActivator.cs" />
|
|
||||||
<Compile Include="PropertyHelper.cs" />
|
<Compile Include="PropertyHelper.cs" />
|
||||||
<Compile Include="TypeExtensions.cs" />
|
<Compile Include="TypeExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
|
||||||
{
|
|
||||||
internal class PropertyActivator<TContext>
|
|
||||||
{
|
|
||||||
private readonly Func<TContext, object> _valueAccessor;
|
|
||||||
private readonly Action<object, object> _fastPropertySetter;
|
|
||||||
|
|
||||||
public PropertyActivator(PropertyInfo propertyInfo,
|
|
||||||
Func<TContext, object> valueAccessor)
|
|
||||||
{
|
|
||||||
PropertyInfo = propertyInfo;
|
|
||||||
_valueAccessor = valueAccessor;
|
|
||||||
_fastPropertySetter = PropertyHelper.MakeFastPropertySetter(propertyInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyInfo PropertyInfo { get; private set; }
|
|
||||||
|
|
||||||
public object Activate(object view, TContext context)
|
|
||||||
{
|
|
||||||
var value = _valueAccessor(context);
|
|
||||||
_fastPropertySetter(view, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of properties on a type that are decorated with
|
|
||||||
/// the specified activateAttributeType and have setters.
|
|
||||||
/// </summary>
|
|
||||||
public static PropertyActivator<TContext>[] GetPropertiesToActivate(
|
|
||||||
Type type,
|
|
||||||
Type activateAttributeType,
|
|
||||||
Func<PropertyInfo, PropertyActivator<TContext>> createActivateInfo)
|
|
||||||
{
|
|
||||||
return type.GetRuntimeProperties()
|
|
||||||
.Where(property =>
|
|
||||||
property.IsDefined(activateAttributeType) &&
|
|
||||||
property.GetIndexParameters().Length == 0 &&
|
|
||||||
property.SetMethod != null &&
|
|
||||||
!property.SetMethod.IsStatic)
|
|
||||||
.Select(createActivateInfo)
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
|
|
@ -17,9 +19,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DefaultControllerActivator : IControllerActivator
|
public class DefaultControllerActivator : IControllerActivator
|
||||||
{
|
{
|
||||||
private readonly Func<Type, PropertyActivator<ActionContext>[]> _getPropertiesToActivate;
|
private readonly Func<Type, PropertyActivator[]> _getPropertiesToActivate;
|
||||||
private readonly IReadOnlyDictionary<Type, Func<ActionContext, object>> _valueAccessorLookup;
|
private readonly Func<PropertyInfo, PropertyActivator> _createActivateInfo;
|
||||||
private readonly ConcurrentDictionary<Type, PropertyActivator<ActionContext>[]> _injectActions;
|
private readonly ReadOnlyDictionary<Type, Func<ActionContext, object>> _valueAccessorLookup;
|
||||||
|
private readonly ConcurrentDictionary<Type, PropertyActivator[]> _injectActions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the DefaultControllerActivator class.
|
/// Initializes a new instance of the DefaultControllerActivator class.
|
||||||
|
|
@ -27,11 +30,9 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public DefaultControllerActivator()
|
public DefaultControllerActivator()
|
||||||
{
|
{
|
||||||
_valueAccessorLookup = CreateValueAccessorLookup();
|
_valueAccessorLookup = CreateValueAccessorLookup();
|
||||||
_injectActions = new ConcurrentDictionary<Type, PropertyActivator<ActionContext>[]>();
|
_getPropertiesToActivate = GetPropertiesToActivate;
|
||||||
_getPropertiesToActivate = type =>
|
_createActivateInfo = CreateActivateInfo;
|
||||||
PropertyActivator<ActionContext>.GetPropertiesToActivate(type,
|
_injectActions = new ConcurrentDictionary<Type, PropertyActivator[]>();
|
||||||
typeof(ActivateAttribute),
|
|
||||||
CreateActivateInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -58,7 +59,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IReadOnlyDictionary<Type, Func<ActionContext, object>> CreateValueAccessorLookup()
|
protected virtual ReadOnlyDictionary<Type, Func<ActionContext, object>> CreateValueAccessorLookup()
|
||||||
{
|
{
|
||||||
var dictionary = new Dictionary<Type, Func<ActionContext, object>>
|
var dictionary = new Dictionary<Type, Func<ActionContext, object>>
|
||||||
{
|
{
|
||||||
|
|
@ -77,11 +78,20 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return dictionary;
|
return new ReadOnlyDictionary<Type, Func<ActionContext, object>>(dictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyActivator<ActionContext> CreateActivateInfo(
|
private PropertyActivator[] GetPropertiesToActivate(Type controllerType)
|
||||||
PropertyInfo property)
|
{
|
||||||
|
var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||||
|
return controllerType.GetProperties(bindingFlags)
|
||||||
|
.Where(property => property.IsDefined(typeof(ActivateAttribute)) &&
|
||||||
|
property.GetSetMethod(nonPublic: true) != null)
|
||||||
|
.Select(_createActivateInfo)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PropertyActivator CreateActivateInfo(PropertyInfo property)
|
||||||
{
|
{
|
||||||
Func<ActionContext, object> valueAccessor;
|
Func<ActionContext, object> valueAccessor;
|
||||||
if (!_valueAccessorLookup.TryGetValue(property.PropertyType, out valueAccessor))
|
if (!_valueAccessorLookup.TryGetValue(property.PropertyType, out valueAccessor))
|
||||||
|
|
@ -93,7 +103,29 @@ namespace Microsoft.AspNet.Mvc
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PropertyActivator<ActionContext>(property, valueAccessor);
|
return new PropertyActivator(property,
|
||||||
|
valueAccessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class PropertyActivator
|
||||||
|
{
|
||||||
|
private readonly PropertyInfo _propertyInfo;
|
||||||
|
private readonly Func<ActionContext, object> _valueAccessor;
|
||||||
|
private readonly Action<object, object> _fastPropertySetter;
|
||||||
|
|
||||||
|
public PropertyActivator(PropertyInfo propertyInfo,
|
||||||
|
Func<ActionContext, object> valueAccessor)
|
||||||
|
{
|
||||||
|
_propertyInfo = propertyInfo;
|
||||||
|
_valueAccessor = valueAccessor;
|
||||||
|
_fastPropertySetter = PropertyHelper.MakeFastPropertySetter(propertyInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate(object instance, ActionContext context)
|
||||||
|
{
|
||||||
|
var value = _valueAccessor(context);
|
||||||
|
_fastPropertySetter(instance, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,11 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
public class InjectChunkVisitor : MvcCSharpCodeVisitor
|
public class InjectChunkVisitor : MvcCSharpCodeVisitor
|
||||||
{
|
{
|
||||||
private readonly List<InjectChunk> _injectChunks = new List<InjectChunk>();
|
private readonly List<InjectChunk> _injectChunks = new List<InjectChunk>();
|
||||||
private readonly string _activateAttribute;
|
|
||||||
|
|
||||||
public InjectChunkVisitor([NotNull] CSharpCodeWriter writer,
|
public InjectChunkVisitor([NotNull] CSharpCodeWriter writer,
|
||||||
[NotNull] CodeGeneratorContext context,
|
[NotNull] CodeGeneratorContext context)
|
||||||
[NotNull] string activateAttributeName)
|
|
||||||
: base(writer, context)
|
: base(writer, context)
|
||||||
{
|
{
|
||||||
_activateAttribute = '[' + activateAttributeName + ']';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<InjectChunk> InjectChunks
|
public List<InjectChunk> InjectChunks
|
||||||
|
|
@ -28,14 +25,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
|
|
||||||
protected override void Visit([NotNull] InjectChunk chunk)
|
protected override void Visit([NotNull] InjectChunk chunk)
|
||||||
{
|
{
|
||||||
Writer.WriteLine(_activateAttribute);
|
if (Context.Host.DesignTimeMode)
|
||||||
|
|
||||||
// Some of the chunks that we visit are either InjectDescriptors that are added by default or
|
|
||||||
// are chunks from _ViewStart files and are not associated with any Spans. Invoking
|
|
||||||
// CreateExpressionMapping to produce line mappings on these chunks would fail. We'll skip
|
|
||||||
// generating code mappings for these chunks. This makes sense since the chunks do not map
|
|
||||||
// to any code in the current view.
|
|
||||||
if (Context.Host.DesignTimeMode && chunk.Association != null)
|
|
||||||
{
|
{
|
||||||
Writer.WriteLine("public");
|
Writer.WriteLine("public");
|
||||||
var code = string.Format(CultureInfo.InvariantCulture,
|
var code = string.Format(CultureInfo.InvariantCulture,
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.AspNet.Mvc.Razor.Host;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents information about an injected property.
|
|
||||||
/// </summary>
|
|
||||||
public class InjectDescriptor
|
|
||||||
{
|
|
||||||
public InjectDescriptor(string typeName, string memberName)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(typeName))
|
|
||||||
{
|
|
||||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpy, "typeName");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(memberName))
|
|
||||||
{
|
|
||||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpy, "memberName");
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeName = typeName;
|
|
||||||
MemberName = memberName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the type name of the injected property
|
|
||||||
/// </summary>
|
|
||||||
public string TypeName { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of the injected property.
|
|
||||||
/// </summary>
|
|
||||||
public string MemberName { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
<Compile Include="IMvcRazorHost.cs" />
|
<Compile Include="IMvcRazorHost.cs" />
|
||||||
<Compile Include="InjectChunk.cs" />
|
<Compile Include="InjectChunk.cs" />
|
||||||
<Compile Include="InjectChunkVisitor.cs" />
|
<Compile Include="InjectChunkVisitor.cs" />
|
||||||
<Compile Include="InjectDescriptor.cs" />
|
|
||||||
<Compile Include="InjectParameterGenerator.cs" />
|
<Compile Include="InjectParameterGenerator.cs" />
|
||||||
<Compile Include="ModelChunk.cs" />
|
<Compile Include="ModelChunk.cs" />
|
||||||
<Compile Include="ModelChunkVisitor.cs" />
|
<Compile Include="ModelChunkVisitor.cs" />
|
||||||
|
|
@ -34,7 +33,6 @@
|
||||||
<Compile Include="MvcCSharpCodeVistor.cs" />
|
<Compile Include="MvcCSharpCodeVistor.cs" />
|
||||||
<Compile Include="MvcRazorCodeParser.cs" />
|
<Compile Include="MvcRazorCodeParser.cs" />
|
||||||
<Compile Include="MvcRazorHost.cs" />
|
<Compile Include="MvcRazorHost.cs" />
|
||||||
<Compile Include="MvcRazorHostOptions.cs" />
|
|
||||||
<Compile Include="Properties\Resources.Designer.cs" />
|
<Compile Include="Properties\Resources.Designer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -13,17 +12,11 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
public class MvcCSharpCodeBuilder : CSharpCodeBuilder
|
public class MvcCSharpCodeBuilder : CSharpCodeBuilder
|
||||||
{
|
{
|
||||||
private readonly MvcRazorHostOptions _hostOptions;
|
public MvcCSharpCodeBuilder([NotNull] CodeGeneratorContext context)
|
||||||
|
|
||||||
public MvcCSharpCodeBuilder([NotNull] CodeGeneratorContext context,
|
|
||||||
[NotNull] MvcRazorHostOptions hostOptions)
|
|
||||||
: base(context)
|
: base(context)
|
||||||
{
|
{
|
||||||
_hostOptions = hostOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string Model { get; set; }
|
|
||||||
|
|
||||||
protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
|
protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
|
||||||
{
|
{
|
||||||
// Grab the last model chunk so it gets intellisense.
|
// Grab the last model chunk so it gets intellisense.
|
||||||
|
|
@ -32,8 +25,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var modelChunk = Context.CodeTreeBuilder.CodeTree.Chunks.OfType<ModelChunk>()
|
var modelChunk = Context.CodeTreeBuilder.CodeTree.Chunks.OfType<ModelChunk>()
|
||||||
.LastOrDefault();
|
.LastOrDefault();
|
||||||
|
|
||||||
Model = modelChunk != null ? modelChunk.ModelType : _hostOptions.DefaultModel;
|
|
||||||
|
|
||||||
// If there were any model chunks then we need to modify the class declaration signature.
|
// If there were any model chunks then we need to modify the class declaration signature.
|
||||||
if (modelChunk != null)
|
if (modelChunk != null)
|
||||||
{
|
{
|
||||||
|
|
@ -55,18 +46,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
|
|
||||||
protected override void BuildConstructor([NotNull] CSharpCodeWriter writer)
|
protected override void BuildConstructor([NotNull] CSharpCodeWriter writer)
|
||||||
{
|
{
|
||||||
// TODO: Move this to a proper extension point. Right now, we don't have a place to print out properties
|
|
||||||
// in the generated view.
|
|
||||||
// Tracked by #773
|
|
||||||
base.BuildConstructor(writer);
|
|
||||||
|
|
||||||
writer.WriteLineHiddenDirective();
|
writer.WriteLineHiddenDirective();
|
||||||
|
|
||||||
var injectVisitor = new InjectChunkVisitor(writer, Context, _hostOptions.ActivateAttributeName);
|
var injectVisitor = new InjectChunkVisitor(writer, Context);
|
||||||
injectVisitor.Accept(Context.CodeTreeBuilder.CodeTree.Chunks);
|
injectVisitor.Accept(Context.CodeTreeBuilder.CodeTree.Chunks);
|
||||||
|
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
writer.WriteLineHiddenDirective();
|
writer.WriteLineHiddenDirective();
|
||||||
|
|
||||||
|
var arguments = injectVisitor.InjectChunks
|
||||||
|
.Select(chunk => new KeyValuePair<string, string>(chunk.TypeName,
|
||||||
|
chunk.MemberName));
|
||||||
|
using (writer.BuildConstructor("public", Context.ClassName, arguments))
|
||||||
|
{
|
||||||
|
foreach (var inject in injectVisitor.InjectChunks)
|
||||||
|
{
|
||||||
|
writer.WriteStartAssignment("this." + inject.MemberName)
|
||||||
|
.Write(inject.MemberName)
|
||||||
|
.WriteLine(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.AspNet.Razor;
|
using Microsoft.AspNet.Razor;
|
||||||
using Microsoft.AspNet.Razor.Generator;
|
using Microsoft.AspNet.Razor.Generator;
|
||||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||||
|
|
@ -26,8 +24,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
"Microsoft.AspNet.Mvc.Rendering"
|
"Microsoft.AspNet.Mvc.Rendering"
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly MvcRazorHostOptions _hostOptions;
|
|
||||||
|
|
||||||
// CodeGenerationContext.DefaultBaseClass is set to MyBaseType<dynamic>.
|
// CodeGenerationContext.DefaultBaseClass is set to MyBaseType<dynamic>.
|
||||||
// This field holds the type name without the generic decoration (MyBaseType)
|
// This field holds the type name without the generic decoration (MyBaseType)
|
||||||
private readonly string _baseType;
|
private readonly string _baseType;
|
||||||
|
|
@ -40,11 +36,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
public MvcRazorHost(string baseType)
|
public MvcRazorHost(string baseType)
|
||||||
: base(new CSharpRazorCodeLanguage())
|
: base(new CSharpRazorCodeLanguage())
|
||||||
{
|
{
|
||||||
// TODO: this needs to flow from the application rather than being initialized here.
|
|
||||||
// Tracked by #774
|
|
||||||
_hostOptions = new MvcRazorHostOptions();
|
|
||||||
_baseType = baseType;
|
_baseType = baseType;
|
||||||
DefaultBaseClass = baseType + '<' + _hostOptions.DefaultModel + '>';
|
DefaultBaseClass = baseType + "<dynamic>";
|
||||||
GeneratedClassContext = new GeneratedClassContext(
|
GeneratedClassContext = new GeneratedClassContext(
|
||||||
executeMethodName: "ExecuteAsync",
|
executeMethodName: "ExecuteAsync",
|
||||||
writeMethodName: "Write",
|
writeMethodName: "Write",
|
||||||
|
|
@ -80,34 +73,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
|
|
||||||
public override CodeBuilder DecorateCodeBuilder(CodeBuilder incomingBuilder, CodeGeneratorContext context)
|
public override CodeBuilder DecorateCodeBuilder(CodeBuilder incomingBuilder, CodeGeneratorContext context)
|
||||||
{
|
{
|
||||||
UpdateCodeBuilder(context);
|
return new MvcCSharpCodeBuilder(context);
|
||||||
return new MvcCSharpCodeBuilder(context, _hostOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateCodeBuilder(CodeGeneratorContext context)
|
|
||||||
{
|
|
||||||
var currentChunks = context.CodeTreeBuilder.CodeTree.Chunks;
|
|
||||||
var existingInjects = new HashSet<string>(currentChunks.OfType<InjectChunk>()
|
|
||||||
.Select(c => c.MemberName),
|
|
||||||
StringComparer.Ordinal);
|
|
||||||
|
|
||||||
var modelChunk = currentChunks.OfType<ModelChunk>()
|
|
||||||
.LastOrDefault();
|
|
||||||
var model = _hostOptions.DefaultModel;
|
|
||||||
if (modelChunk != null)
|
|
||||||
{
|
|
||||||
model = modelChunk.ModelType;
|
|
||||||
}
|
|
||||||
model = '<' + model + '>';
|
|
||||||
|
|
||||||
// Locate properties by name that haven't already been injected in to the View.
|
|
||||||
var propertiesToAdd = _hostOptions.DefaultInjectedProperties
|
|
||||||
.Where(c => !existingInjects.Contains(c.MemberName));
|
|
||||||
foreach (var property in propertiesToAdd)
|
|
||||||
{
|
|
||||||
var memberName = property.MemberName.Replace("<TModel>", model);
|
|
||||||
currentChunks.Add(new InjectChunk(property.TypeName, memberName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents configuration options for the Razor Host
|
|
||||||
/// </summary>
|
|
||||||
public class MvcRazorHostOptions
|
|
||||||
{
|
|
||||||
public MvcRazorHostOptions()
|
|
||||||
{
|
|
||||||
DefaultModel = "dynamic";
|
|
||||||
ActivateAttributeName = "Microsoft.AspNet.Mvc.ActivateAttribute";
|
|
||||||
DefaultInjectedProperties = new List<InjectDescriptor>()
|
|
||||||
{
|
|
||||||
new InjectDescriptor("Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<TModel>", "Html")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the model that is used by default for generated views
|
|
||||||
/// when no model is explicily specified. Defaults to dynamic.
|
|
||||||
/// </summary>
|
|
||||||
public string DefaultModel { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the attribue that is used to decorate properties that are injected and need to
|
|
||||||
/// be activated.
|
|
||||||
/// </summary>
|
|
||||||
public string ActivateAttributeName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the list of properties that are injected by default.
|
|
||||||
/// </summary>
|
|
||||||
public IList<InjectDescriptor> DefaultInjectedProperties { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,22 +10,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Host
|
||||||
private static readonly ResourceManager _resourceManager
|
private static readonly ResourceManager _resourceManager
|
||||||
= new ResourceManager("Microsoft.AspNet.Mvc.Razor.Host.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
= new ResourceManager("Microsoft.AspNet.Mvc.Razor.Host.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Argument cannot be null or empty.
|
|
||||||
/// </summary>
|
|
||||||
internal static string ArgumentCannotBeNullOrEmpy
|
|
||||||
{
|
|
||||||
get { return GetString("ArgumentCannotBeNullOrEmpy"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Argument cannot be null or empty.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatArgumentCannotBeNullOrEmpy()
|
|
||||||
{
|
|
||||||
return GetString("ArgumentCannotBeNullOrEmpy");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
|
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -117,9 +117,6 @@
|
||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="ArgumentCannotBeNullOrEmpy" xml:space="preserve">
|
|
||||||
<value>Argument cannot be null or empty.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
|
<data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
|
||||||
<value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
|
<value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provides methods to activate properties on a view instance.
|
|
||||||
/// </summary>
|
|
||||||
public interface IRazorViewActivator
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// When implemented in a type, activates an instantiated view.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="view">The view to activate.</param>
|
|
||||||
/// <param name="context">The <see cref="ViewContext"/> for the view.</param>
|
|
||||||
void Activate(RazorView view, ViewContext context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -30,11 +30,9 @@
|
||||||
<Compile Include="Compilation\RoslynCompilationService.cs" />
|
<Compile Include="Compilation\RoslynCompilationService.cs" />
|
||||||
<Compile Include="Extensions\DictionaryExtensions.cs" />
|
<Compile Include="Extensions\DictionaryExtensions.cs" />
|
||||||
<Compile Include="HelperResult.cs" />
|
<Compile Include="HelperResult.cs" />
|
||||||
<Compile Include="IRazorViewActivator.cs" />
|
|
||||||
<Compile Include="PositionTagged.cs" />
|
<Compile Include="PositionTagged.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs" />
|
<Compile Include="Properties\Resources.Designer.cs" />
|
||||||
<Compile Include="RazorView.cs" />
|
<Compile Include="RazorView.cs" />
|
||||||
<Compile Include="RazorViewActivator.cs" />
|
|
||||||
<Compile Include="RazorViewOfT.cs" />
|
<Compile Include="RazorViewOfT.cs" />
|
||||||
<Compile Include="Razor\IRazorCompilationService.cs" />
|
<Compile Include="Razor\IRazorCompilationService.cs" />
|
||||||
<Compile Include="Razor\RazorCompilationService.cs" />
|
<Compile Include="Razor\RazorCompilationService.cs" />
|
||||||
|
|
@ -44,4 +42,4 @@
|
||||||
<Compile Include="ViewEngine\VirtualPathViewFactory.cs" />
|
<Compile Include="ViewEngine\VirtualPathViewFactory.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -186,22 +186,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("SectionsNotRendered"), p0);
|
return string.Format(CultureInfo.CurrentCulture, GetString("SectionsNotRendered"), p0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// View of type '{0}' cannot be instatiated by '{1}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string ViewCannotBeActivated
|
|
||||||
{
|
|
||||||
get { return GetString("ViewCannotBeActivated"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// View of type '{0}' cannot be instatiated by '{1}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatViewCannotBeActivated(object p0, object p1)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("ViewCannotBeActivated"), p0, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// View '{0}' must have extension '{1}' when the view represents a full path.
|
/// View '{0}' must have extension '{1}' when the view represents a full path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
|
||||||
using Microsoft.Framework.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public class RazorViewActivator : IRazorViewActivator
|
|
||||||
{
|
|
||||||
private readonly ITypeActivator _typeActivator;
|
|
||||||
private readonly ConcurrentDictionary<Type, ViewActivationInfo> _activationInfo;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the RazorViewActivator class.
|
|
||||||
/// </summary>
|
|
||||||
public RazorViewActivator(ITypeActivator typeActivator)
|
|
||||||
{
|
|
||||||
_typeActivator = typeActivator;
|
|
||||||
_activationInfo = new ConcurrentDictionary<Type, ViewActivationInfo>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Activates the specified view by using the specified ViewContext.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="view">The view to activate.</param>
|
|
||||||
/// <param name="context">The ViewContext for the executing view.</param>
|
|
||||||
public void Activate([NotNull] RazorView view, [NotNull] ViewContext context)
|
|
||||||
{
|
|
||||||
var activationInfo = _activationInfo.GetOrAdd(view.GetType(),
|
|
||||||
CreateViewActivationInfo);
|
|
||||||
|
|
||||||
context.ViewData = CreateViewDataDictionary(context, activationInfo);
|
|
||||||
|
|
||||||
for (var i = 0; i < activationInfo.PropertyActivators.Length; i++)
|
|
||||||
{
|
|
||||||
var activateInfo = activationInfo.PropertyActivators[i];
|
|
||||||
activateInfo.Activate(view, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ViewDataDictionary CreateViewDataDictionary(ViewContext context, ViewActivationInfo activationInfo)
|
|
||||||
{
|
|
||||||
// Create a ViewDataDictionary<TModel> if the ViewContext.ViewData is not set or the type of
|
|
||||||
// ViewContext.ViewData is an incompatibile type.
|
|
||||||
if (context.ViewData == null)
|
|
||||||
{
|
|
||||||
// Create ViewDataDictionary<TModel>(metadataProvider);
|
|
||||||
return (ViewDataDictionary)_typeActivator.CreateInstance(context.HttpContext.RequestServices,
|
|
||||||
activationInfo.ViewDataDictionaryType);
|
|
||||||
}
|
|
||||||
else if (context.ViewData.GetType() != activationInfo.ViewDataDictionaryType)
|
|
||||||
{
|
|
||||||
// Create ViewDataDictionary<TModel>(ViewDataDictionary);
|
|
||||||
return (ViewDataDictionary)_typeActivator.CreateInstance(context.HttpContext.RequestServices,
|
|
||||||
activationInfo.ViewDataDictionaryType,
|
|
||||||
context.ViewData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return context.ViewData;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ViewActivationInfo CreateViewActivationInfo(Type type)
|
|
||||||
{
|
|
||||||
var typeInfo = type.GetTypeInfo();
|
|
||||||
Type viewDataType;
|
|
||||||
if (!typeInfo.IsGenericType || typeInfo.GenericTypeArguments.Length != 1)
|
|
||||||
{
|
|
||||||
// Ensure that the view is of the type RazorView<TModel>.
|
|
||||||
var message = Resources.FormatViewCannotBeActivated(type.FullName, GetType().FullName);
|
|
||||||
throw new InvalidOperationException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var modelType = typeInfo.GenericTypeArguments[0];
|
|
||||||
viewDataType = typeof(ViewDataDictionary<>).MakeGenericType(modelType);
|
|
||||||
|
|
||||||
return new ViewActivationInfo
|
|
||||||
{
|
|
||||||
ViewDataDictionaryType = viewDataType,
|
|
||||||
PropertyActivators = PropertyActivator<ViewContext>.GetPropertiesToActivate(type,
|
|
||||||
typeof(ActivateAttribute),
|
|
||||||
CreateActivateInfo)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private PropertyActivator<ViewContext> CreateActivateInfo(PropertyInfo property)
|
|
||||||
{
|
|
||||||
Func<ViewContext, object> valueAccessor;
|
|
||||||
if (property.PropertyType.IsAssignableFrom(typeof(ViewDataDictionary)))
|
|
||||||
{
|
|
||||||
valueAccessor = context => context.ViewData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valueAccessor = context =>
|
|
||||||
{
|
|
||||||
var serviceProvider = context.HttpContext.RequestServices;
|
|
||||||
var value = serviceProvider.GetService(property.PropertyType);
|
|
||||||
var canHasViewContext = value as ICanHasViewContext;
|
|
||||||
if (canHasViewContext != null)
|
|
||||||
{
|
|
||||||
canHasViewContext.Contextualize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PropertyActivator<ViewContext>(property, valueAccessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ViewActivationInfo
|
|
||||||
{
|
|
||||||
public PropertyActivator<ViewContext>[] PropertyActivators { get; set; }
|
|
||||||
|
|
||||||
public Type ViewDataDictionaryType { get; set; }
|
|
||||||
|
|
||||||
public Action<object, object> ViewDataDictionarySetter { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
namespace Microsoft.AspNet.Mvc.Razor
|
||||||
|
|
@ -16,15 +19,43 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Activate]
|
public ViewDataDictionary<TModel> ViewData { get; private set; }
|
||||||
public ViewDataDictionary<TModel> ViewData { get; set; }
|
|
||||||
|
public IHtmlHelper<TModel> Html { get; set; }
|
||||||
|
|
||||||
public override Task RenderAsync([NotNull] ViewContext context)
|
public override Task RenderAsync([NotNull] ViewContext context)
|
||||||
{
|
{
|
||||||
var viewActivator = context.HttpContext.RequestServices.GetService<IRazorViewActivator>();
|
ViewData = context.ViewData as ViewDataDictionary<TModel>;
|
||||||
viewActivator.Activate(this, context);
|
if (ViewData == null)
|
||||||
|
{
|
||||||
|
if (context.ViewData != null)
|
||||||
|
{
|
||||||
|
ViewData = new ViewDataDictionary<TModel>(context.ViewData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var metadataProvider = context.HttpContext.RequestServices.GetService<IModelMetadataProvider>();
|
||||||
|
ViewData = new ViewDataDictionary<TModel>(metadataProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have new ViewDataDictionary; make sure it's visible everywhere.
|
||||||
|
context.ViewData = ViewData;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitHelpers(context);
|
||||||
|
|
||||||
return base.RenderAsync(context);
|
return base.RenderAsync(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitHelpers(ViewContext context)
|
||||||
|
{
|
||||||
|
Html = context.HttpContext.RequestServices.GetService<IHtmlHelper<TModel>>();
|
||||||
|
|
||||||
|
var contextable = Html as ICanHasViewContext;
|
||||||
|
if (contextable != null)
|
||||||
|
{
|
||||||
|
contextable.Contextualize(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,9 +150,6 @@
|
||||||
<data name="SectionsNotRendered" xml:space="preserve">
|
<data name="SectionsNotRendered" xml:space="preserve">
|
||||||
<value>The following sections have been defined but have not been rendered: '{0}'.</value>
|
<value>The following sections have been defined but have not been rendered: '{0}'.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ViewCannotBeActivated" xml:space="preserve">
|
|
||||||
<value>View of type '{0}' cannot be instatiated by '{1}'.</value>
|
|
||||||
</data>
|
|
||||||
<data name="ViewMustEndInExtension" xml:space="preserve">
|
<data name="ViewMustEndInExtension" xml:space="preserve">
|
||||||
<value>View '{0}' must have extension '{1}' when the view represents a full path.</value>
|
<value>View '{0}' must have extension '{1}' when the view represents a full path.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
yield return describe.Scoped<ICompositeViewEngine, CompositeViewEngine>();
|
yield return describe.Scoped<ICompositeViewEngine, CompositeViewEngine>();
|
||||||
yield return describe.Transient<IRazorCompilationService, RazorCompilationService>();
|
yield return describe.Transient<IRazorCompilationService, RazorCompilationService>();
|
||||||
yield return describe.Transient<IVirtualPathViewFactory, VirtualPathViewFactory>();
|
yield return describe.Transient<IVirtualPathViewFactory, VirtualPathViewFactory>();
|
||||||
yield return describe.Singleton<IRazorViewActivator, RazorViewActivator>();
|
|
||||||
|
|
||||||
yield return describe.Transient<INestedProvider<ActionDescriptorProviderContext>,
|
yield return describe.Transient<INestedProvider<ActionDescriptorProviderContext>,
|
||||||
ReflectedActionDescriptorProvider>();
|
ReflectedActionDescriptorProvider>();
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
var writer = new CSharpCodeWriter();
|
var writer = new CSharpCodeWriter();
|
||||||
var context = CreateContext();
|
var context = CreateContext();
|
||||||
|
|
||||||
var visitor = new InjectChunkVisitor(writer, context, "ActivateAttribute");
|
var visitor = new InjectChunkVisitor(writer, context);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
visitor.Accept(new Chunk[]
|
visitor.Accept(new Chunk[]
|
||||||
|
|
@ -41,15 +41,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected =
|
var expected =
|
||||||
@"[ActivateAttribute]
|
@"public MyType1 MyPropertyName1 { get; private set; }
|
||||||
public MyType1 MyPropertyName1 { get; private set; }
|
|
||||||
[ActivateAttribute]
|
|
||||||
public MyType2 @MyPropertyName2 { get; private set; }
|
public MyType2 @MyPropertyName2 { get; private set; }
|
||||||
";
|
";
|
||||||
var writer = new CSharpCodeWriter();
|
var writer = new CSharpCodeWriter();
|
||||||
var context = CreateContext();
|
var context = CreateContext();
|
||||||
|
|
||||||
var visitor = new InjectChunkVisitor(writer, context, "ActivateAttribute");
|
var visitor = new InjectChunkVisitor(writer, context);
|
||||||
var factory = SpanFactory.CreateCsHtml();
|
var factory = SpanFactory.CreateCsHtml();
|
||||||
var node = (Span)factory.Code("Some code")
|
var node = (Span)factory.Code("Some code")
|
||||||
.As(new InjectParameterGenerator("MyType", "MyPropertyName"));
|
.As(new InjectParameterGenerator("MyType", "MyPropertyName"));
|
||||||
|
|
@ -71,15 +69,13 @@ public MyType2 @MyPropertyName2 { get; private set; }
|
||||||
public void Visit_WithDesignTimeHost_GeneratesPropertiesAndLinePragmas_ForInjectChunks()
|
public void Visit_WithDesignTimeHost_GeneratesPropertiesAndLinePragmas_ForInjectChunks()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = @"[Microsoft.AspNet.Mvc.ActivateAttribute]
|
var expected = @"public
|
||||||
public
|
|
||||||
#line 1 """"
|
#line 1 """"
|
||||||
MyType1 MyPropertyName1
|
MyType1 MyPropertyName1
|
||||||
|
|
||||||
#line default
|
#line default
|
||||||
#line hidden
|
#line hidden
|
||||||
{ get; private set; }
|
{ get; private set; }
|
||||||
[Microsoft.AspNet.Mvc.ActivateAttribute]
|
|
||||||
public
|
public
|
||||||
#line 1 """"
|
#line 1 """"
|
||||||
MyType2 @MyPropertyName2
|
MyType2 @MyPropertyName2
|
||||||
|
|
@ -92,7 +88,7 @@ MyType2 @MyPropertyName2
|
||||||
var context = CreateContext();
|
var context = CreateContext();
|
||||||
context.Host.DesignTimeMode = true;
|
context.Host.DesignTimeMode = true;
|
||||||
|
|
||||||
var visitor = new InjectChunkVisitor(writer, context, "Microsoft.AspNet.Mvc.ActivateAttribute");
|
var visitor = new InjectChunkVisitor(writer, context);
|
||||||
var factory = SpanFactory.CreateCsHtml();
|
var factory = SpanFactory.CreateCsHtml();
|
||||||
var node = (Span)factory.Code("Some code")
|
var node = (Span)factory.Code("Some code")
|
||||||
.As(new InjectParameterGenerator("MyType", "MyPropertyName"));
|
.As(new InjectParameterGenerator("MyType", "MyPropertyName"));
|
||||||
|
|
@ -125,40 +121,7 @@ MyType2 @MyPropertyName2
|
||||||
var expectedLineMappings = new List<LineMapping>
|
var expectedLineMappings = new List<LineMapping>
|
||||||
{
|
{
|
||||||
BuildLineMapping(1, 0, 1, 32, 3, 0, 17),
|
BuildLineMapping(1, 0, 1, 32, 3, 0, 17),
|
||||||
BuildLineMapping(28, 1, 8, 573, 26, 8, 20)
|
BuildLineMapping(28, 1, 8, 442, 21, 8, 20)
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
|
||||||
GeneratorResults results;
|
|
||||||
using (var buffer = new StringTextBuffer(source))
|
|
||||||
{
|
|
||||||
results = engine.GenerateCode(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.True(results.Success);
|
|
||||||
Assert.Equal(expectedCode, results.GeneratedCode);
|
|
||||||
Assert.Empty(results.ParserErrors);
|
|
||||||
Assert.Equal(expectedLineMappings, results.DesignTimeLineMappings);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void InjectVisitorWithModel_GeneratesCorrectLineMappings()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var host = new MvcRazorHost("RazorView")
|
|
||||||
{
|
|
||||||
DesignTimeMode = true
|
|
||||||
};
|
|
||||||
host.NamespaceImports.Clear();
|
|
||||||
var engine = new RazorTemplateEngine(host);
|
|
||||||
var source = ReadResource("TestFiles/Input/InjectWithModel.cshtml");
|
|
||||||
var expectedCode = ReadResource("TestFiles/Output/InjectWithModel.cs");
|
|
||||||
var expectedLineMappings = new List<LineMapping>
|
|
||||||
{
|
|
||||||
BuildLineMapping(7, 0, 7, 126, 6, 7, 7),
|
|
||||||
BuildLineMapping(24, 1, 8, 562, 26, 8, 20),
|
|
||||||
BuildLineMapping(54, 2, 8, 732, 34, 8, 22)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@
|
||||||
<Compile Include="SpanFactory\SpanFactoryExtensions.cs" />
|
<Compile Include="SpanFactory\SpanFactoryExtensions.cs" />
|
||||||
<Compile Include="SpanFactory\UnclassifiedSpanConstructor.cs" />
|
<Compile Include="SpanFactory\UnclassifiedSpanConstructor.cs" />
|
||||||
<Compile Include="StringTextBuffer.cs" />
|
<Compile Include="StringTextBuffer.cs" />
|
||||||
<Compile Include="TestFiles\Input\InjectWithModel.cshtml" />
|
|
||||||
<Compile Include="TestFiles\Output\InjectWithModel.cs" />
|
|
||||||
<Compile Include="TestFiles\Output\Model.cs" />
|
<Compile Include="TestFiles\Output\Model.cs" />
|
||||||
<Compile Include="TestFiles\Output\Inject.cs" />
|
<Compile Include="TestFiles\Output\Inject.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
@model MyModel
|
|
||||||
@inject MyApp MyPropertyName
|
|
||||||
@inject MyService<TModel> Html
|
|
||||||
|
|
@ -17,11 +17,6 @@ using MyNamespace
|
||||||
#pragma warning restore 219
|
#pragma warning restore 219
|
||||||
}
|
}
|
||||||
#line hidden
|
#line hidden
|
||||||
public __CompiledTemplate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#line hidden
|
|
||||||
[Microsoft.AspNet.Mvc.ActivateAttribute]
|
|
||||||
public
|
public
|
||||||
#line 2 ""
|
#line 2 ""
|
||||||
MyApp MyPropertyName
|
MyApp MyPropertyName
|
||||||
|
|
@ -29,10 +24,12 @@ using MyNamespace
|
||||||
#line default
|
#line default
|
||||||
#line hidden
|
#line hidden
|
||||||
{ get; private set; }
|
{ get; private set; }
|
||||||
[Microsoft.AspNet.Mvc.ActivateAttribute]
|
|
||||||
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<TModel> Html { get; private set; }
|
|
||||||
|
|
||||||
#line hidden
|
#line hidden
|
||||||
|
public __CompiledTemplate(MyApp MyPropertyName)
|
||||||
|
{
|
||||||
|
this.MyPropertyName = MyPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma warning disable 1998
|
#pragma warning disable 1998
|
||||||
public override async Task ExecuteAsync()
|
public override async Task ExecuteAsync()
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
namespace Razor
|
|
||||||
{
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
public class __CompiledTemplate : RazorView<
|
|
||||||
#line 1 ""
|
|
||||||
MyModel
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
>
|
|
||||||
{
|
|
||||||
private static object @__o;
|
|
||||||
private void @__RazorDesignTimeHelpers__()
|
|
||||||
{
|
|
||||||
#pragma warning disable 219
|
|
||||||
#pragma warning restore 219
|
|
||||||
}
|
|
||||||
#line hidden
|
|
||||||
public __CompiledTemplate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#line hidden
|
|
||||||
[Microsoft.AspNet.Mvc.ActivateAttribute]
|
|
||||||
public
|
|
||||||
#line 2 ""
|
|
||||||
MyApp MyPropertyName
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
{ get; private set; }
|
|
||||||
[Microsoft.AspNet.Mvc.ActivateAttribute]
|
|
||||||
public
|
|
||||||
#line 3 ""
|
|
||||||
MyService<TModel> Html
|
|
||||||
|
|
||||||
#line default
|
|
||||||
#line hidden
|
|
||||||
{ get; private set; }
|
|
||||||
|
|
||||||
#line hidden
|
|
||||||
|
|
||||||
#pragma warning disable 1998
|
|
||||||
public override async Task ExecuteAsync()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#pragma warning restore 1998
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,15 +16,12 @@
|
||||||
#pragma warning disable 219
|
#pragma warning disable 219
|
||||||
#pragma warning restore 219
|
#pragma warning restore 219
|
||||||
}
|
}
|
||||||
|
#line hidden
|
||||||
|
|
||||||
#line hidden
|
#line hidden
|
||||||
public __CompiledTemplate()
|
public __CompiledTemplate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#line hidden
|
|
||||||
[Microsoft.AspNet.Mvc.ActivateAttribute]
|
|
||||||
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<TModel> Html { get; private set; }
|
|
||||||
|
|
||||||
#line hidden
|
|
||||||
|
|
||||||
#pragma warning disable 1998
|
#pragma warning disable 1998
|
||||||
public override async Task ExecuteAsync()
|
public override async Task ExecuteAsync()
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="MvcRazorCodeParserTest.cs" />
|
<Compile Include="MvcRazorCodeParserTest.cs" />
|
||||||
<Compile Include="RazorCompilationServiceTest.cs" />
|
<Compile Include="RazorCompilationServiceTest.cs" />
|
||||||
<Compile Include="RazorViewActivatorTest.cs" />
|
|
||||||
<Compile Include="RazorViewEngineTest.cs" />
|
<Compile Include="RazorViewEngineTest.cs" />
|
||||||
<Compile Include="RazorViewTest.cs" />
|
<Compile Include="RazorViewTest.cs" />
|
||||||
<Compile Include="SpanFactory.cs" />
|
<Compile Include="SpanFactory.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.Http;
|
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
|
||||||
using Microsoft.AspNet.Routing;
|
|
||||||
using Moq;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor
|
|
||||||
{
|
|
||||||
public class RazorViewActivatorTest
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void Activate_ActivatesAndContextualizesPropertiesOnViews()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var activator = new RazorViewActivator();
|
|
||||||
var instance = new TestView();
|
|
||||||
|
|
||||||
var myService = new MyService();
|
|
||||||
var helper = Mock.Of<IHtmlHelper<object>>();
|
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
|
|
||||||
.Returns(myService);
|
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
|
|
||||||
.Returns(helper);
|
|
||||||
var httpContext = new Mock<HttpContext>();
|
|
||||||
httpContext.SetupGet(c => c.RequestServices)
|
|
||||||
.Returns(serviceProvider.Object);
|
|
||||||
var routeContext = new RouteContext(httpContext.Object);
|
|
||||||
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
|
|
||||||
var viewContext = new ViewContext(actionContext,
|
|
||||||
instance,
|
|
||||||
new ViewDataDictionary(Mock.Of<IModelMetadataProvider>()),
|
|
||||||
TextWriter.Null);
|
|
||||||
// Act
|
|
||||||
activator.Activate(instance, viewContext);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Same(helper, instance.Html);
|
|
||||||
Assert.Same(myService, instance.MyService);
|
|
||||||
Assert.Same(viewContext, myService.ViewContext);
|
|
||||||
Assert.Null(instance.MyService2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract class TestViewBase : RazorView
|
|
||||||
{
|
|
||||||
[Activate]
|
|
||||||
public MyService MyService { get; set; }
|
|
||||||
|
|
||||||
public MyService MyService2 { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestView : TestViewBase
|
|
||||||
{
|
|
||||||
[Activate]
|
|
||||||
internal IHtmlHelper<object> Html { get; private set; }
|
|
||||||
|
|
||||||
public override Task ExecuteAsync()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MyService : ICanHasViewContext
|
|
||||||
{
|
|
||||||
public ViewContext ViewContext { get; private set; }
|
|
||||||
|
|
||||||
public void Contextualize(ViewContext viewContext)
|
|
||||||
{
|
|
||||||
ViewContext = viewContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue