// 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.Collections.Generic; using System.Reflection; using Microsoft.AspNet.Mvc.Rendering; namespace Microsoft.AspNet.Mvc { /// /// Represents the that is registered by default. /// public class DefaultViewComponentActivator : IViewComponentActivator { private readonly Func[]> _getPropertiesToActivate; private readonly IReadOnlyDictionary> _valueAccessorLookup; private readonly ConcurrentDictionary[]> _injectActions; /// /// Initializes a new instance of class. /// public DefaultViewComponentActivator() { _valueAccessorLookup = CreateValueAccessorLookup(); _injectActions = new ConcurrentDictionary[]>(); _getPropertiesToActivate = type => PropertyActivator.GetPropertiesToActivate( type, typeof(ActivateAttribute), CreateActivateInfo); } /// public void Activate([NotNull] object viewComponent, [NotNull] ViewContext context) { var propertiesToActivate = _injectActions.GetOrAdd(viewComponent.GetType(), _getPropertiesToActivate); for (var i = 0; i < propertiesToActivate.Length; i++) { var activateInfo = propertiesToActivate[i]; activateInfo.Activate(viewComponent, context); } } /// /// Creates a lookup dictionary for the values to be activated. /// /// Returns a readonly dictionary of the values corresponding to the types. protected virtual IReadOnlyDictionary> CreateValueAccessorLookup() { return new Dictionary> { { typeof(ViewContext), (context) => context }, { typeof(ViewDataDictionary), (context) => { return new ViewDataDictionary(context.ViewData) { Model = null }; } } }; } private PropertyActivator CreateActivateInfo(PropertyInfo property) { Func valueAccessor; if (!_valueAccessorLookup.TryGetValue(property.PropertyType, out valueAccessor)) { valueAccessor = (viewContext) => { var serviceProvider = viewContext.HttpContext.RequestServices; var service = serviceProvider.GetService(property.PropertyType); if (typeof(ICanHasViewContext).IsAssignableFrom(property.PropertyType)) { ((ICanHasViewContext)service).Contextualize(viewContext); } return service; }; } return new PropertyActivator(property, valueAccessor); } } }