Skip to content

Instantly share code, notes, and snippets.

@JeremyCaney
Last active December 16, 2019 00:35
Show Gist options
  • Save JeremyCaney/00c04b1b9f40d9743793cd45dfaaa606 to your computer and use it in GitHub Desktop.
Save JeremyCaney/00c04b1b9f40d9743793cd45dfaaa606 to your computer and use it in GitHub Desktop.
Reference version of an `IControllerActivator` used to configure OnTopic in ASP.NET Core.
/*==============================================================================================================================
| Author Ignia, LLC
| Client OrganizationName
| Project Website
\=============================================================================================================================*/
using System;
using Ignia.Topics;
using Ignia.Topics.AspNetCore.Mvc;
using Ignia.Topics.AspNetCore.Mvc.Components;
using Ignia.Topics.AspNetCore.Mvc.Controllers;
using Ignia.Topics.Data.Caching;
using Ignia.Topics.Data.Sql;
using Ignia.Topics.Mapping;
using Ignia.Topics.Reflection;
using Ignia.Topics.Repositories;
using Ignia.Topics.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Ignia.Topics.AspNetCore.Mvc.Host.Components;
namespace OrganizationName.Web {
/*============================================================================================================================
| CLASS: ACTIVATOR
\---------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Responsible for creating instances of factories in response to web requests. Represents the Composition Root for
/// Dependency Injection.
/// </summary>
public class OrganizationNameActivator : IControllerActivator, IViewComponentActivator {
/*==========================================================================================================================
| PRIVATE INSTANCES
\-------------------------------------------------------------------------------------------------------------------------*/
private readonly ITypeLookupService _typeLookupService = null;
private readonly ITopicMappingService _topicMappingService = null;
private readonly ITopicRepository _topicRepository = null;
/*==========================================================================================================================
| HIERARCHICAL TOPIC MAPPING SERVICE
\-------------------------------------------------------------------------------------------------------------------------*/
private readonly IHierarchicalTopicMappingService<NavigationTopicViewModel> _hierarchicalTopicMappingService = null;
/*==========================================================================================================================
| CONSTRUCTOR
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Establishes a new instance of the <see cref="OrganizationNameFactory"/>, including any shared dependencies to be used
/// across instances of controllers.
/// </summary>
/// <remarks>
/// The constructor is responsible for establishing dependencies with the singleton lifestyle so that they are available
/// to all requests.
/// </remarks>
public OrganizationNameActivator(string connectionString) {
/*------------------------------------------------------------------------------------------------------------------------
| Initialize Topic Repository
\-----------------------------------------------------------------------------------------------------------------------*/
var sqlTopicRepository = new SqlTopicRepository(connectionString);
var cachedTopicRepository = new CachedTopicRepository(sqlTopicRepository);
/*------------------------------------------------------------------------------------------------------------------------
| Preload repository
\-----------------------------------------------------------------------------------------------------------------------*/
_topicRepository = cachedTopicRepository;
_typeLookupService = new DynamicTopicViewModelLookupService();
_topicMappingService = new TopicMappingService(_topicRepository, _typeLookupService);
_ = _topicRepository.Load();
/*------------------------------------------------------------------------------------------------------------------------
| CONSTRUCT HIERARCHICAL TOPIC MAPPING SERVICE
\-----------------------------------------------------------------------------------------------------------------------*/
var hierarchyService = new HierarchicalTopicMappingService<NavigationTopicViewModel>(
_topicRepository,
_topicMappingService
);
_hierarchicalTopicMappingService = new CachedHierarchicalTopicMappingService<NavigationTopicViewModel>(hierarchyService);
}
/*==========================================================================================================================
| METHOD: CREATE
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Registers dependencies, and injects them into new instances of controllers in response to each request.
/// </summary>
/// <returns>A concrete instance of an <see cref="IController"/>.</returns>
public object Create(ControllerContext context) {
/*------------------------------------------------------------------------------------------------------------------------
| Determine controller type
\-----------------------------------------------------------------------------------------------------------------------*/
Type controllerType = context.ActionDescriptor.ControllerTypeInfo.AsType();
/*------------------------------------------------------------------------------------------------------------------------
| Configure and return appropriate controller
\-----------------------------------------------------------------------------------------------------------------------*/
return controllerType.Name switch {
nameof(HomeController) => return new HomeController(),
nameof(TopicController) => new TopicController(_topicRepository, _topicMappingService),
nameof(RedirectController) => new RedirectController(_topicRepository),
nameof(SitemapController) => new SitemapController(_topicRepository),
_ => throw new Exception($"Unknown controller {controllerType.Name}")
};
}
/// <summary>
/// Registers dependencies, and injects them into new instances of view components in response to each request.
/// </summary>
/// <returns>A concrete instance of an <see cref="IViewComponent"/>.</returns>
public object Create(ViewComponentContext context) {
/*------------------------------------------------------------------------------------------------------------------------
| Determine view component type
\-----------------------------------------------------------------------------------------------------------------------*/
var viewComponentType = context.ViewComponentDescriptor.TypeInfo.AsType();
/*------------------------------------------------------------------------------------------------------------------------
| Resolve
\-----------------------------------------------------------------------------------------------------------------------*/
return viewComponentType.Name switch {
nameof(MenuViewComponent)
=> new MenuViewComponent(_topicRepository, _hierarchicalTopicMappingService),
nameof(PageLevelNavigationViewComponent)
=> new PageLevelNavigationViewComponent(_topicRepository, _hierarchicalTopicMappingService),
_ => throw new Exception($"Unknown view component {viewComponentType.Name}")
};
}
/*==========================================================================================================================
| METHOD: RELEASE
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Responds to a request to release resources associated with a particular controller.
/// </summary>
public void Release(ControllerContext context, object controller) { }
/// <summary>
/// Responds to a request to release resources associated with a particular view component.
/// </summary>
public void Release(ViewComponentContext context, object viewComponent) { }
} //Class
} //Namespace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment