Skip to content

Commit

Permalink
Minor cleanup, doc updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
tillig committed Sep 11, 2015
1 parent 4f395c9 commit 63db0ab
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 239 deletions.
219 changes: 117 additions & 102 deletions src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs
Original file line number Diff line number Diff line change
@@ -1,102 +1,117 @@
// This software is part of the Autofac IoC container
// Copyright (c) 2007 - 2008 Autofac Contributors
// http://autofac.org
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Integration.Mef.Util;

namespace Autofac.Integration.Mef
{
/// <summary>
/// Support the <see cref="System.Lazy{T, TMetadata}"/>
/// types automatically whenever type T is registered with the container.
/// Metadata values come from the component registration's metadata.
/// When a dependency of a lazy type is used, the instantiation of the underlying
/// component will be delayed until the Value property is first accessed.
/// </summary>
class LazyWithMetadataRegistrationSource : IRegistrationSource
{
static readonly MethodInfo CreateLazyRegistrationMethod = typeof(LazyWithMetadataRegistrationSource).GetMethod(
"CreateLazyRegistration", BindingFlags.Static | BindingFlags.NonPublic);

delegate IComponentRegistration RegistrationCreator(Service service, IComponentRegistration valueRegistration);

public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
if (registrationAccessor == null)
{
throw new ArgumentNullException("registrationAccessor");
}
var swt = service as IServiceWithType;
if (swt == null || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Lazy<,>)))
return Enumerable.Empty<IComponentRegistration>();

var valueType = swt.ServiceType.GetGenericArguments()[0];
var metaType = swt.ServiceType.GetGenericArguments()[1];

var valueService = swt.ChangeType(valueType);

var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate(
typeof(RegistrationCreator),
CreateLazyRegistrationMethod.MakeGenericMethod(valueType, metaType));

return registrationAccessor(valueService)
.Select(v => registrationCreator(service, v));
}

public bool IsAdapterForIndividualComponents
{
get { return true; }
}

public override string ToString()
{
return LazyWithMetadataRegistrationSourceResources.LazyWithMetadataRegistrationSourceDescription;
}

// ReSharper disable UnusedMember.Local
static IComponentRegistration CreateLazyRegistration<T, TMeta>(Service providedService, IComponentRegistration valueRegistration)
// ReSharper restore UnusedMember.Local
{
var rb = RegistrationBuilder.ForDelegate(
(c, p) =>
{
var context = c.Resolve<IComponentContext>();
return new Lazy<T, TMeta>(
() => (T)context.ResolveComponent(valueRegistration, p),
AttributedModelServices.GetMetadataView<TMeta>(valueRegistration.Target.Metadata));
})
.As(providedService)
.Targeting(valueRegistration);

return rb.CreateRegistration();
}
}
}
// This software is part of the Autofac IoC container
// Copyright (c) 2007 - 2008 Autofac Contributors
// http://autofac.org
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Integration.Mef.Util;

namespace Autofac.Integration.Mef
{
/// <summary>
/// Support the <see cref="System.Lazy{T, TMetadata}"/>
/// types automatically whenever type T is registered with the container.
/// </summary>
/// <remarks>
/// Metadata values come from the component registration's metadata.
/// When a dependency of a lazy type is used, the instantiation of the underlying
/// component will be delayed until the <see cref="Lazy{T}.Value"/> property
/// is first accessed.
/// </remarks>
internal class LazyWithMetadataRegistrationSource : IRegistrationSource
{
private static readonly MethodInfo CreateLazyRegistrationMethod = typeof(LazyWithMetadataRegistrationSource).GetMethod("CreateLazyRegistration", BindingFlags.Static | BindingFlags.NonPublic);

private delegate IComponentRegistration RegistrationCreator(Service service, IComponentRegistration valueRegistration);

public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
if (registrationAccessor == null)
{
throw new ArgumentNullException("registrationAccessor");
}

var swt = service as IServiceWithType;
if (swt == null || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Lazy<,>)))
{
return Enumerable.Empty<IComponentRegistration>();
}

var valueType = swt.ServiceType.GetGenericArguments()[0];
var metaType = swt.ServiceType.GetGenericArguments()[1];
var valueService = swt.ChangeType(valueType);
var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate(
typeof(RegistrationCreator),
CreateLazyRegistrationMethod.MakeGenericMethod(valueType, metaType));

return registrationAccessor(valueService)
.Select(v => registrationCreator(service, v));
}

public bool IsAdapterForIndividualComponents
{
get
{
return true;
}
}

public override string ToString()
{
return LazyWithMetadataRegistrationSourceResources.LazyWithMetadataRegistrationSourceDescription;
}

/// <summary>
/// Lazy registration creator called via reflection by the source
/// to generate a <see cref="Lazy{T, TMetadata}"/> component.
/// </summary>
/// <typeparam name="T">The type of service being resolved.</typeparam>
/// <typeparam name="TMetadata">The type of metadata object associated with the service.</typeparam>
/// <param name="providedService">The service for which the component registration is being generated.</param>
/// <param name="valueRegistration">The registration that should provide the component value.</param>
/// <returns>
/// An <see cref="IComponentRegistration"/> containing a <see cref="Lazy{T, TMetadata}"/>.
/// </returns>
private static IComponentRegistration CreateLazyRegistration<T, TMetadata>(Service providedService, IComponentRegistration valueRegistration)
{
var rb = RegistrationBuilder.ForDelegate(
(c, p) =>
{
var context = c.Resolve<IComponentContext>();
return new Lazy<T, TMetadata>(
() => (T)context.ResolveComponent(valueRegistration, p),
AttributedModelServices.GetMetadataView<TMetadata>(valueRegistration.Target.Metadata));
})
.As(providedService)
.Targeting(valueRegistration);

return rb.CreateRegistration();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Integration.Mef.Util;
using Autofac.Features.Metadata;
using Autofac.Integration.Mef.Util;

namespace Autofac.Integration.Mef
{
Expand All @@ -40,28 +39,36 @@ namespace Autofac.Integration.Mef
/// types automatically whenever type T is registered with the container.
/// Metadata values come from the component registration's metadata.
/// </summary>
class StronglyTypedMetadataRegistrationSource : IRegistrationSource
internal class StronglyTypedMetadataRegistrationSource : IRegistrationSource
{
static readonly MethodInfo CreateMetaRegistrationMethod = typeof(StronglyTypedMetadataRegistrationSource).GetMethod(
"CreateMetaRegistration", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly MethodInfo CreateMetaRegistrationMethod = typeof(StronglyTypedMetadataRegistrationSource).GetMethod("CreateMetaRegistration", BindingFlags.Static | BindingFlags.NonPublic);

delegate IComponentRegistration RegistrationCreator(Service service, IComponentRegistration valueRegistration);
private delegate IComponentRegistration RegistrationCreator(Service service, IComponentRegistration valueRegistration);

public bool IsAdapterForIndividualComponents
{
get
{
return true;
}
}

public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
if (registrationAccessor == null)
{
throw new ArgumentNullException("registrationAccessor");
}

var swt = service as IServiceWithType;
if (swt == null || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Meta<,>)))
{
return Enumerable.Empty<IComponentRegistration>();
}

var valueType = swt.ServiceType.GetGenericArguments()[0];
var metaType = swt.ServiceType.GetGenericArguments()[1];

var valueService = swt.ChangeType(valueType);

var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate(
typeof(RegistrationCreator),
CreateMetaRegistrationMethod.MakeGenericMethod(valueType, metaType));
Expand All @@ -70,19 +77,23 @@ public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Fun
.Select(v => registrationCreator.Invoke(service, v));
}

public bool IsAdapterForIndividualComponents
{
get { return true; }
}

public override string ToString()
{
return StronglyTypedMetadataRegistrationSourceResources.StronglyTypedMetaRegistrationSourceDescription;
}

// ReSharper disable UnusedMember.Local
static IComponentRegistration CreateMetaRegistration<T, TMetadata>(Service providedService, IComponentRegistration valueRegistration)
// ReSharper restore UnusedMember.Local
/// <summary>
/// Strongly typed registration creator called via reflection by the source
/// to generate a <see cref="Meta{T, TMetadata}"/> component.
/// </summary>
/// <typeparam name="T">The type of service being resolved.</typeparam>
/// <typeparam name="TMetadata">The type of metadata object associated with the service.</typeparam>
/// <param name="providedService">The service for which the component registration is being generated.</param>
/// <param name="valueRegistration">The registration that should provide the component value.</param>
/// <returns>
/// An <see cref="IComponentRegistration"/> containing a <see cref="Meta{T, TMetadata}"/>.
/// </returns>
private static IComponentRegistration CreateMetaRegistration<T, TMetadata>(Service providedService, IComponentRegistration valueRegistration)
{
var rb = RegistrationBuilder
.ForDelegate((c, p) => new Meta<T, TMetadata>(
Expand Down
Loading

0 comments on commit 63db0ab

Please sign in to comment.