Skip to content

Instantly share code, notes, and snippets.

@seangwright
Last active July 10, 2019 00:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seangwright/4918a5c5488a9bb617ebdf1c2557fe6b to your computer and use it in GitHub Desktop.
Save seangwright/4918a5c5488a9bb617ebdf1c2557fe6b to your computer and use it in GitHub Desktop.
Kentico 12: Design Patterns Part 4 - Adding Dependency Injection to the CMS
public static class DependencyResolverConfig
{
public static IContainer BuildContainer()
{
var builder = new ContainerBuilder();
// My registration classes use a "fluent" interface, always returning the ContainerBuilder
// so the next call can be chained off the previous
var container = builder
.RegisterApplicationTypes()
.RegisterMvcTypes()
.RegisterCmsTypes()
.RegisterApiTypes()
.Build();
return container;
}
}
// In a separate file MvcRegistration.cs I would have the following
public static class MvcRegistration
{
public static ContainerBuilder RegisterMvcTypes(this ContainerBuilder builder)
{
var assemblies = new Assembly[]
{
typeof(MvcApplication).Assembly,
typeof(ApplicationErrorHandlerModule).Assembly,
typeof(SitemapController).Assembly
};
builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterControllers(assemblies);
builder.RegisterFilterProvider();
builder.RegisterType<ActivityLoggingActionFilter>()
.AsActionFilterFor<Controller>()
.InstancePerRequest();
builder.RegisterAssemblyTypes(assemblies)
.Where(t => t.IsClass && !t.IsAbstract && t.Name.EndsWith("RouteRegistry"))
.AsImplementedInterfaces();
builder.Register(ctx => HttpContext.Current.GetOwinContext().Authentication);
builder.Register(ctx => HttpContext.Current.GetOwinContext().Get<SignInManager>());
builder.Register(ctx => HttpContext.Current.GetOwinContext().Get<UserManager>());
builder
.Register(ctx => new DefaultSiteMetaService<SiteMeta>(() => new SiteMeta("Default")))
.As<ISiteMetaService<SiteMeta>>()
.InstancePerRequest();
builder
.RegisterType<MetaTagActionFilterAttribute>()
.AsActionFilterFor<Controller>()
.InstancePerRequest()
.PropertiesAutowired();
return builder;
}
}
// Add this using
// using CMSService = CMS.Core.Service;
public class KenticoRegistrationSource : IRegistrationSource
{
/// <summary>
/// Gets whether the registrations provided by this source are 1:1 adapters on top of other components (I.e. like Meta, Func or Owned.)
/// </summary>
public bool IsAdapterForIndividualComponents => false;
/// <summary>
/// Retrieve registrations for an unregistered service, to be used by the container.
/// </summary>
/// <param name="service">The service that was requested.</param>
/// <param name="registrationAccessor">A function that will return existing registrations for a service.</param>
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
// There are other registration exists in the container
if (registrationAccessor(service).Any())
{
return Enumerable.Empty<IComponentRegistration>();
}
if (!(service is IServiceWithType swt))
{
return Enumerable.Empty<IComponentRegistration>();
}
object instance = null;
if (CMSService.IsRegistered(swt.ServiceType))
{
instance = CMSService.Resolve(swt.ServiceType);
}
if (instance is null)
{
return Enumerable.Empty<IComponentRegistration>();
}
// Register the instance in the container
return new[] { RegistrationBuilder.ForDelegate(swt.ServiceType, (c, p) => instance).CreateRegistration() };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment