diff --git a/Lamar.sln b/Lamar.sln index e640c5c7..2dc7e504 100644 --- a/Lamar.sln +++ b/Lamar.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2036 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.202 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lamar.Testing", "src\Lamar.Testing\Lamar.Testing.csproj", "{865C14C3-4B54-46EC-B394-9BAD73905086}" EndProject @@ -41,15 +41,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserApp", "src\UserApp\User EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bug-124-Widgets", "Bug-124-Widgets", "{317DED50-F632-48EB-8E02-E1B6739B35E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Widget.Aspect.Logger", "src\Aspect.Logger\Widget.Aspect.Logger.csproj", "{A367AE1C-B39D-438B-BADD-3B7E368DDF97}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Widget.Aspect.Logger", "src\Aspect.Logger\Widget.Aspect.Logger.csproj", "{A367AE1C-B39D-438B-BADD-3B7E368DDF97}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Widget.Instance", "Widget.Instance\Widget.Instance.csproj", "{6F721733-9012-4434-A830-2F5E9A6A926B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Widget.Instance", "Widget.Instance\Widget.Instance.csproj", "{6F721733-9012-4434-A830-2F5E9A6A926B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Widget.Core", "Widget.Core\Widget.Core.csproj", "{178C596D-65D9-42F9-927C-DF63F348DCA5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Widget.Core", "Widget.Core\Widget.Core.csproj", "{178C596D-65D9-42F9-927C-DF63F348DCA5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Widget.Registration", "Widget.Registration\Widget.Registration.csproj", "{39F01E1B-0549-422A-A60F-747C1CDF0C08}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Widget.Registration", "Widget.Registration\Widget.Registration.csproj", "{39F01E1B-0549-422A-A60F-747C1CDF0C08}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LamarCodeGeneration", "src\LamarCodeGeneration\LamarCodeGeneration.csproj", "{2030BA2A-5D44-4BDA-9EF7-7EB0BC7A1C6F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LamarCodeGeneration", "src\LamarCodeGeneration\LamarCodeGeneration.csproj", "{2030BA2A-5D44-4BDA-9EF7-7EB0BC7A1C6F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lamar.AutoFactory", "src\Lamar.AutoFactory\Lamar.AutoFactory.csproj", "{2250C640-88AF-4DA5-A1D1-7BC3717E1D60}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lamar.AutoFactory.Testing", "src\Lamar.AutoFactory.Testing\Lamar.AutoFactory.Testing.csproj", "{EFB244CD-F185-4052-A4B5-4A869682D616}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -145,6 +149,14 @@ Global {2030BA2A-5D44-4BDA-9EF7-7EB0BC7A1C6F}.Debug|Any CPU.Build.0 = Debug|Any CPU {2030BA2A-5D44-4BDA-9EF7-7EB0BC7A1C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU {2030BA2A-5D44-4BDA-9EF7-7EB0BC7A1C6F}.Release|Any CPU.Build.0 = Release|Any CPU + {2250C640-88AF-4DA5-A1D1-7BC3717E1D60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2250C640-88AF-4DA5-A1D1-7BC3717E1D60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2250C640-88AF-4DA5-A1D1-7BC3717E1D60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2250C640-88AF-4DA5-A1D1-7BC3717E1D60}.Release|Any CPU.Build.0 = Release|Any CPU + {EFB244CD-F185-4052-A4B5-4A869682D616}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EFB244CD-F185-4052-A4B5-4A869682D616}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EFB244CD-F185-4052-A4B5-4A869682D616}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EFB244CD-F185-4052-A4B5-4A869682D616}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Lamar.AutoFactory.Testing/AutoFactoryTester.cs b/src/Lamar.AutoFactory.Testing/AutoFactoryTester.cs new file mode 100644 index 00000000..7952c1fc --- /dev/null +++ b/src/Lamar.AutoFactory.Testing/AutoFactoryTester.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using Shouldly; +using Xunit; + +namespace Lamar.AutoFactory.Testing +{ + public class AutoFactoryTester + { + private Container container; + + public AutoFactoryTester() + { + } + + [Fact] + public void Can_build_the_factory() + { + container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + factory.ShouldNotBeNull(); + } + + [Fact] + public void Can_resolve_component() + { + container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var component = factory.CreateDummyService(); + + component.ShouldNotBeNull(); + component.ShouldBeOfType(); + } + + [Fact] + public void Can_resolve_generic_components_via_a_generic_method() + { + container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var component = factory.CreateService(); + + component.ShouldNotBeNull(); + component.ShouldBeOfType(); + } + + [Fact] + public void Can_resolve_a_closed_generic_return_type() + { + container = new Container(cfg => + { + cfg.For>().Use(); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var component = factory.CreateHandler(); + + component.ShouldNotBeNull(); + component.ShouldBeOfType(); + } + + [Fact] + public void ResolveServiceWithRedundantExplicitArguments() + { + container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var component = factory.CreateDummyService("John", "Smith"); + + component.ShouldSatisfyAllConditions( + () => component.ShouldNotBeNull(), + () => component.ShouldBeOfType(), + () => component.Name.ShouldBeNull() + ); + } + + [Fact] + public void TryToResolveNotRegisteredNamedService() + { + container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().Add().Named("direct"); + cfg.For().Add().Named("reversed"); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var component = factory.GetNamedDummyService("unknown", "John", "Smith"); + + component.ShouldBeNull(); + } + + [Fact] + public void ResolveServiceNames() + { + container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().Add().Named("direct"); + cfg.For().Add().Named("reversed"); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var names = factory.GetNames(); + + names.ShouldBe(new[] { string.Empty, "direct", "reversed" }, true); + } + } + + public interface IHandler + { + void Handle(T thing); + } + + public class Message + { + } + + public class MessageHandler : IHandler + { + public void Handle(Message thing) + { + } + } + + // SAMPLE: IDummyService + public interface IDummyService + { + string Name { get; } + } + + // ENDSAMPLE + + // SAMPLE: DummyService + public class DummyService : IDummyService + { + public string Name { get; set; } + } + + // ENDSAMPLE + + public class DummyServiceWithName : IDummyService + { + public DummyServiceWithName(string namePart1, string namePart2) + { + Name = string.Format("{0} {1}", namePart1, namePart2); + } + + public string Name { get; set; } + } + + public class DummyServiceWithReversedName : IDummyService + { + public DummyServiceWithReversedName(string namePart1, string namePart2) + { + Name = string.Format("{0} {1}", namePart2, namePart1); + } + + public string Name { get; set; } + } + + // SAMPLE: IDummyFactory + public interface IDummyFactory + { + // This method will return the names of all registered implementations of TService. + IList GetNames(); + + // This method will just create the default IDummyService implementation. + IDummyService CreateDummyService(); + + // This method will just create the default IDummyService implementation and pass namePart1 and namePart2 as + // dependencies. + IDummyService CreateDummyService(string namePart1, string namePart2); + + // This method will create IDummyService implementation with serviceName name. + IDummyService GetNamedDummyService(string serviceName, string namePart1, string namePart2); + + // Generic methods are also allowed as factory methods. + TService CreateService(); + + // Something that is common for event-sourcing implementations. + IHandler CreateHandler(); + } + + // ENDSAMPLE +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory.Testing/Lamar.AutoFactory.Testing.csproj b/src/Lamar.AutoFactory.Testing/Lamar.AutoFactory.Testing.csproj new file mode 100644 index 00000000..24e97692 --- /dev/null +++ b/src/Lamar.AutoFactory.Testing/Lamar.AutoFactory.Testing.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp2.0 + Lamar.AutoFactory.Testing + Lamar.AutoFactory.Testing + true + false + false + false + + + + + + + + + + + + + + + + diff --git a/src/Lamar.AutoFactory.Testing/Properties/AssemblyInfo.cs b/src/Lamar.AutoFactory.Testing/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..703536c1 --- /dev/null +++ b/src/Lamar.AutoFactory.Testing/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("StructureMap.AutoFactory.Testing")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fa9f954b-ee4a-4172-b38b-a342df9ec15f")] diff --git a/src/Lamar.AutoFactory.Testing/ProxyFactoryTests.cs b/src/Lamar.AutoFactory.Testing/ProxyFactoryTests.cs new file mode 100644 index 00000000..656918b4 --- /dev/null +++ b/src/Lamar.AutoFactory.Testing/ProxyFactoryTests.cs @@ -0,0 +1,59 @@ +using System; +using Castle.DynamicProxy; +using Moq; +using Shouldly; +using Xunit; + +namespace Lamar.AutoFactory.Testing +{ + public class ProxyFactoryTests + { + public interface IFactory + { + IService CreateService(); + } + + public interface IService + { + } + + public class Service : IService + { + } + + [Fact] + public void Should_create_a_proxy_factory() + { + var proxyGenerator = new ProxyGenerator(); + var context = new Mock().Object; + + var proxyFactory = new ProxyFactory(proxyGenerator, context, new DefaultAutoFactoryConventionProvider()); + + var factory = proxyFactory.Create(); + + factory.ShouldNotBeNull(); + } + + [Fact] + public void Should_build_the_service_by_return_type_from_context() + { + var proxyGenerator = new ProxyGenerator(); + var contextMock = new Mock(); + var containerMock = new Mock(); + + var service = new Service(); + + contextMock.Setup(x => x.GetInstance()).Returns(containerMock.Object); + containerMock.Setup(x => x.TryGetInstance(typeof(IService))).Returns(service); + + var proxyFactory = new ProxyFactory(proxyGenerator, contextMock.Object, new DefaultAutoFactoryConventionProvider()); + + var factory = proxyFactory.Create(); + + var built = factory.CreateService(); + + built.ShouldNotBeNull(); + built.ShouldBe(service); + } + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory.Testing/Samples.cs b/src/Lamar.AutoFactory.Testing/Samples.cs new file mode 100644 index 00000000..50a42b24 --- /dev/null +++ b/src/Lamar.AutoFactory.Testing/Samples.cs @@ -0,0 +1,37 @@ +using System; +using Shouldly; +using Xunit; + +namespace Lamar.AutoFactory.Testing +{ + public class Samples + { + // SAMPLE: simple-factory + [Fact] + public void Simple_factory_creation() + { + var container = new Container(cfg => + { + cfg.For().Use(); + cfg.For().CreateFactory(); + }); + + var factory = container.GetInstance(); + + var component = factory.CreateDummyService(); + + component.ShouldNotBeNull(); + component.ShouldBeOfType(); + } + + // ENDSAMPLE + } + + // SAMPLE: ISimpleDummyFactory + public interface ISimpleDummyFactory + { + IDummyService CreateDummyService(); + } + + // ENDSAMPLE +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/AutoFactoryExtensions.cs b/src/Lamar.AutoFactory/AutoFactoryExtensions.cs new file mode 100644 index 00000000..810d6e5c --- /dev/null +++ b/src/Lamar.AutoFactory/AutoFactoryExtensions.cs @@ -0,0 +1,74 @@ +using Castle.DynamicProxy; +using System; +using Lamar.IoC.Instances; +using LamarCodeGeneration.Model; +using LamarCodeGeneration.Util; + +namespace Lamar.AutoFactory +{ + public static class AutoFactoryExtensions + { + private static readonly ProxyGenerator proxyGenerator = new ProxyGenerator(); + + public static void CreateFactory(this ServiceRegistry.InstanceExpression expression) + where TPluginType : class + { + CreateFactory(expression, new DefaultAutoFactoryConventionProvider()); + } + + public static void CreateFactory(this ServiceRegistry.InstanceExpression expression, + IAutoFactoryConventionProvider conventionProvider) + where TPluginType : class + { + var callback = CreateFactoryCallback(conventionProvider); + + expression.Use(callback); + } + + public static void CreateFactory( + this ServiceRegistry.InstanceExpression expression) + where TPluginType : class + where TConventionProvider : IAutoFactoryConventionProvider + { + var callback = CreateFactoryCallback(); + + expression.Use(callback); + } + + private static string GetDescription() where TPluginType : class + { + return "AutoFactory builder for " + typeof(TPluginType).GetFullName(); + } + + private static Func CreateFactoryCallback(IAutoFactoryConventionProvider conventionProvider) + where TPluginType : class + { + return ctxt => + { + var proxyFactory = new ProxyFactory(proxyGenerator, ctxt, conventionProvider); + + return proxyFactory.Create(); + }; + } + + private static Func CreateFactoryCallback() + where TPluginType : class + where TConventionProvider : IAutoFactoryConventionProvider + { + return ctxt => + { + var conventionProvider = ctxt.GetInstance(); + + var proxyFactory = new ProxyFactory(proxyGenerator, ctxt, conventionProvider); + + return proxyFactory.Create(); + }; + } + + public static bool HasExplicitName(this Instance instance) + { + // NOTE: I suspect this is a bit too naive + return !instance.Name.Equals("default") && !instance.Name.Equals(Variable.DefaultArgName(instance.ImplementationType)); + } + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/AutoFactoryMethodDefinition.cs b/src/Lamar.AutoFactory/AutoFactoryMethodDefinition.cs new file mode 100644 index 00000000..0bcb4926 --- /dev/null +++ b/src/Lamar.AutoFactory/AutoFactoryMethodDefinition.cs @@ -0,0 +1,20 @@ +using System; + +namespace Lamar.AutoFactory +{ + public class AutoFactoryMethodDefinition : IAutoFactoryMethodDefinition + { + public AutoFactoryMethodDefinition(AutoFactoryMethodType methodType, Type instanceType, string instanceName) + { + MethodType = methodType; + InstanceType = instanceType; + InstanceName = instanceName; + } + + public AutoFactoryMethodType MethodType { get; } + + public Type InstanceType { get; } + + public string InstanceName { get; } + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/AutoFactoryMethodType.cs b/src/Lamar.AutoFactory/AutoFactoryMethodType.cs new file mode 100644 index 00000000..a77bf89e --- /dev/null +++ b/src/Lamar.AutoFactory/AutoFactoryMethodType.cs @@ -0,0 +1,17 @@ +using System; + +namespace Lamar.AutoFactory +{ + public enum AutoFactoryMethodType + { + /// + /// Method is used to create an instance i.e. factory method. + /// + GetInstance = 0, + + /// + /// Special method to return the list of names of registered implementations. + /// + GetNames = 1 + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/DefaultAutoFactoryConventionProvider.cs b/src/Lamar.AutoFactory/DefaultAutoFactoryConventionProvider.cs new file mode 100644 index 00000000..3898057b --- /dev/null +++ b/src/Lamar.AutoFactory/DefaultAutoFactoryConventionProvider.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Lamar.AutoFactory +{ + public class DefaultAutoFactoryConventionProvider : IAutoFactoryConventionProvider + { + public IAutoFactoryMethodDefinition GetMethodDefinition(MethodInfo methodInfo, IList arguments) + { + if (methodInfo.Name.StartsWith("GetNames", StringComparison.OrdinalIgnoreCase) + && methodInfo.IsGenericMethod + && methodInfo.GetGenericArguments().Any() + && methodInfo.ReturnType.IsAssignableFrom(typeof(List))) + { + return new AutoFactoryMethodDefinition(AutoFactoryMethodType.GetNames, methodInfo.GetGenericArguments().First(), null); + } + + var pluginType = methodInfo.ReturnType; + + // do nothing with void methods for now + if (pluginType == typeof(void)) + { + return null; + } + + var name = tryGetInstanceName(methodInfo, arguments); + + var isNamed = !string.IsNullOrEmpty(name); + + return new AutoFactoryMethodDefinition(AutoFactoryMethodType.GetInstance, pluginType, name); + } + + private static string tryGetInstanceName(MethodInfo methodInfo, IList arguments) + { + return methodInfo.Name.StartsWith("GetNamed", StringComparison.OrdinalIgnoreCase) + && arguments.Any() + ? Convert.ToString(arguments.First()) + : null; + } + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/FactoryInterceptor.cs b/src/Lamar.AutoFactory/FactoryInterceptor.cs new file mode 100644 index 00000000..41d86a42 --- /dev/null +++ b/src/Lamar.AutoFactory/FactoryInterceptor.cs @@ -0,0 +1,45 @@ +using System.Linq; +using Castle.DynamicProxy; +using Lamar; + +namespace Lamar.AutoFactory +{ + public class FactoryInterceptor : IInterceptor + { + private readonly IContainer _container; + private readonly IAutoFactoryConventionProvider _conventionProvider; + + public FactoryInterceptor(IContainer container, IAutoFactoryConventionProvider conventionProvider) + { + _container = container; + _conventionProvider = conventionProvider; + } + + public void Intercept(IInvocation invocation) + { + var methodDefinition = _conventionProvider.GetMethodDefinition(invocation.Method, invocation.Arguments); + + if (methodDefinition == null) + { + return; + } + + switch (methodDefinition.MethodType) + { + case AutoFactoryMethodType.GetInstance: + invocation.ReturnValue = !string.IsNullOrEmpty(methodDefinition.InstanceName) + ? _container.TryGetInstance(methodDefinition.InstanceType, methodDefinition.InstanceName) + : _container.TryGetInstance(methodDefinition.InstanceType); + break; + + + case AutoFactoryMethodType.GetNames: + invocation.ReturnValue = _container.Model.AllInstances + .Where(x => x.ServiceType == methodDefinition.InstanceType) + .Select(x => x.Instance.HasExplicitName() ? x.Name : string.Empty) + .ToList(); + break; + } + } + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/IAutoFactoryConventionProvider.cs b/src/Lamar.AutoFactory/IAutoFactoryConventionProvider.cs new file mode 100644 index 00000000..084341f9 --- /dev/null +++ b/src/Lamar.AutoFactory/IAutoFactoryConventionProvider.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Lamar.AutoFactory +{ + public interface IAutoFactoryConventionProvider + { + // SAMPLE: GetMethodDefinition + IAutoFactoryMethodDefinition GetMethodDefinition(MethodInfo methodInfo, IList arguments); + + //ENDSAMPLE + } +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/IAutoFactoryMethodDefinition.cs b/src/Lamar.AutoFactory/IAutoFactoryMethodDefinition.cs new file mode 100644 index 00000000..788385e3 --- /dev/null +++ b/src/Lamar.AutoFactory/IAutoFactoryMethodDefinition.cs @@ -0,0 +1,28 @@ +using System; + +namespace Lamar.AutoFactory +{ + // SAMPLE: IAutoFactoryMethodDefinition + /// + /// Describes how AutoFactory should treat the specific method declared in an abstract factory interface. + /// + public interface IAutoFactoryMethodDefinition + { + /// + /// The method type. See for possible values. + /// + AutoFactoryMethodType MethodType { get; } + + /// + /// The instance type to create. + /// + Type InstanceType { get; } + + /// + /// The instance name if available. + /// + string InstanceName { get; } + } + + // ENDSAMPLE +} \ No newline at end of file diff --git a/src/Lamar.AutoFactory/Lamar.AutoFactory.csproj b/src/Lamar.AutoFactory/Lamar.AutoFactory.csproj new file mode 100644 index 00000000..88188b58 --- /dev/null +++ b/src/Lamar.AutoFactory/Lamar.AutoFactory.csproj @@ -0,0 +1,41 @@ + + + + AutoFactory Support for Lamar + Lamar.AutoFactory + en-US + 1.0.1 + Jeremy D. Miller + net461;netstandard2.0 + true + Lamar.AutoFactory + Lamar.AutoFactory + IoC + http://jasperfx.github.io/lamar + https://raw.githubusercontent.com/JasperFx/lamar/master/README.md + git + git://github.com/jasperfx/lamar + false + false + false + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Lamar.AutoFactory/Properties/AssemblyInfo.cs b/src/Lamar.AutoFactory/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..11505f70 --- /dev/null +++ b/src/Lamar.AutoFactory/Properties/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("StructureMap.AutoFactory")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("cb4b9035-721d-4fec-abc7-51fb4e795ce6")] \ No newline at end of file diff --git a/src/Lamar.AutoFactory/ProxyFactory.cs b/src/Lamar.AutoFactory/ProxyFactory.cs new file mode 100644 index 00000000..c0ba68b2 --- /dev/null +++ b/src/Lamar.AutoFactory/ProxyFactory.cs @@ -0,0 +1,29 @@ +using Castle.DynamicProxy; +using Lamar; +using Lamar.AutoFactory; + +namespace Lamar.AutoFactory +{ + public class ProxyFactory where TPluginType : class + { + private readonly ProxyGenerator _proxyGenerator; + private readonly IServiceContext _context; + private readonly IAutoFactoryConventionProvider _conventionProvider; + + public ProxyFactory(ProxyGenerator proxyGenerator, IServiceContext context, IAutoFactoryConventionProvider conventionProvider) + { + _proxyGenerator = proxyGenerator; + _context = context; + _conventionProvider = conventionProvider; + } + + public TPluginType Create() + { + var container = _context.GetInstance(); + + var interceptor = new FactoryInterceptor(container, _conventionProvider); + + return _proxyGenerator.CreateInterfaceProxyWithoutTarget(interceptor); + } + } +} \ No newline at end of file