public void CreateInstanceBy(CallTarget callTarget, bool owned) { object instance; try { instance = callTarget.method == null ? callTarget.factory(this) : callTarget.method.Compile()(callTarget.self, callTarget.actualArguments); } catch (ServiceCouldNotBeCreatedException e) { if (!string.IsNullOrEmpty(e.Message)) { SetComment(e.Message); } return; } catch (SimpleContainerException e) { if (Status == ServiceStatus.Ok) { SetError(e); } return; } catch (Exception e) { SetError(e); return; } AddInstance(instance, owned, false); }
internal void Instantiate(ContainerService.Builder builder) { LifestyleAttribute lifestyle; if (builder.Type.IsSimpleType()) { builder.SetError("can't create simple type"); } else if (builder.Type == typeof(IContainer)) { builder.AddInstance(this, false, false); } else if (builder.Configuration.ImplementationAssigned) { builder.AddInstance(builder.Configuration.Implementation, builder.Configuration.ContainerOwnsInstance, true); } else if (builder.Configuration.Factory != null) { if (!builder.Context.AnalizeDependenciesOnly) { builder.CreateInstanceBy(CallTarget.F(builder.Configuration.Factory), builder.Configuration.ContainerOwnsInstance); } } else if (builder.Type.IsValueType) { builder.SetError("can't create value type"); } else if (builder.Type.IsGenericType && builder.Type.ContainsGenericParameters) { builder.SetError("can't create open generic"); } else if (!builder.CreateNew && builder.Type.TryGetCustomAttribute(out lifestyle) && lifestyle.Lifestyle == Lifestyle.PerRequest) { const string messageFormat = "service [{0}] with PerRequest lifestyle can't be resolved, use Func<{0}> instead"; builder.SetError(string.Format(messageFormat, builder.Type.FormatName())); } else if (builder.Type.IsAbstract) { InstantiateInterface(builder); } else { InstantiateImplementation(builder); } }
public static bool TryCreate(ContainerService.Builder builder) { var factoryType = builder.Type.GetNestedType("Factory"); if (factoryType == null) { return(false); } var method = factoryType.GetMethod("Create", Type.EmptyTypes); if (method == null) { return(false); } var factory = builder.Context.Container.Resolve(method.DeclaringType, InternalHelpers.emptyStrings, false); if (factory.IsOk()) { builder.CreateInstanceBy(CallTarget.M(method, factory.Single(), new object[0]), true); } return(true); }
internal ServiceDependency InstantiateDependency(ParameterInfo formalParameter, ContainerService.Builder builder) { ValueWithType actualArgument; if (builder.Arguments != null && builder.Arguments.TryGet(formalParameter.Name, out actualArgument)) { return(containerContext.Constant(formalParameter, actualArgument.value)); } var parameters = builder.Configuration.ParametersSource; object actualParameter; if (parameters != null && parameters.TryGet(formalParameter.Name, formalParameter.ParameterType, out actualParameter)) { return(containerContext.Constant(formalParameter, actualParameter)); } var dependencyConfiguration = builder.Configuration.GetOrNull(formalParameter); Type implementationType = null; if (dependencyConfiguration != null) { if (dependencyConfiguration.ValueAssigned) { return(containerContext.Constant(formalParameter, dependencyConfiguration.Value)); } if (dependencyConfiguration.Factory != null) { var dependencyBuilder = new ContainerService.Builder(new ServiceName(formalParameter.ParameterType)) { Context = builder.Context, DependencyName = formalParameter.Name }; builder.Context.Stack.Add(dependencyBuilder); dependencyBuilder.CreateInstanceBy(CallTarget.F(dependencyConfiguration.Factory), true); builder.Context.Stack.RemoveLast(); return(dependencyBuilder.GetService().AsDependency(containerContext, formalParameter.Name, false)); } implementationType = dependencyConfiguration.ImplementationType; } implementationType = implementationType ?? formalParameter.ParameterType; FromResourceAttribute resourceAttribute; if (implementationType == typeof(Stream) && formalParameter.TryGetCustomAttribute(out resourceAttribute)) { var resourceStream = builder.Type.Assembly.GetManifestResourceStream(builder.Type, resourceAttribute.Name); if (resourceStream == null) { return(containerContext.Error(null, formalParameter.Name, "can't find resource [{0}] in namespace of [{1}], assembly [{2}]", resourceAttribute.Name, builder.Type, builder.Type.Assembly.GetName().Name)); } return(containerContext.Resource(formalParameter, resourceAttribute.Name, resourceStream)); } var dependencyName = ServiceName.Parse(implementationType.UnwrapEnumerable(), InternalHelpers.ParseContracts(formalParameter)); if (dependencyName.Type.IsSimpleType()) { if (!formalParameter.HasDefaultValue) { return(containerContext.Error(null, formalParameter.Name, "parameter [{0}] of service [{1}] is not configured", formalParameter.Name, builder.Type.FormatName())); } return(containerContext.Constant(formalParameter, formalParameter.DefaultValue)); } var resultService = ResolveCore(dependencyName, false, null, builder.Context); if (resultService.Status.IsBad()) { return(containerContext.ServiceError(resultService)); } var isEnumerable = dependencyName.Type != implementationType; if (isEnumerable) { return(containerContext.Service(resultService, resultService.GetAllValues())); } if (resultService.Status == ServiceStatus.NotResolved) { if (formalParameter.HasDefaultValue) { return(containerContext.Service(resultService, formalParameter.DefaultValue)); } if (formalParameter.IsDefined <OptionalAttribute>() || formalParameter.IsDefined("CanBeNullAttribute")) { return(containerContext.Service(resultService, null)); } return(containerContext.NotResolved(resultService)); } return(resultService.AsDependency(containerContext, null, false)); }
private void InstantiateImplementation(ContainerService.Builder builder) { if (builder.DontUse()) { builder.SetComment("DontUse"); return; } var result = FactoryCreator.TryCreate(builder) ?? LazyCreator.TryCreate(builder); if (result != null) { builder.AddInstance(result, true, false); return; } if (NestedFactoryCreator.TryCreate(builder)) { return; } if (CtorFactoryCreator.TryCreate(builder)) { return; } if (builder.Type.IsDelegate()) { builder.SetError(string.Format("can't create delegate [{0}]", builder.Type.FormatName())); return; } var constructor = builder.Type.GetConstructor(); if (!constructor.isOk) { builder.SetError(constructor.errorMessage); return; } var formalParameters = constructor.value.GetParameters(); var actualArguments = new object[formalParameters.Length]; var hasServiceNameParameters = false; for (var i = 0; i < formalParameters.Length; i++) { var formalParameter = formalParameters[i]; if (formalParameter.ParameterType == typeof(ServiceName)) { hasServiceNameParameters = true; continue; } var dependency = InstantiateDependency(formalParameter, builder).CastTo(formalParameter.ParameterType); builder.AddDependency(dependency, false); if (dependency.ContainerService != null) { builder.UnionUsedContracts(dependency.ContainerService); } if (builder.Status != ServiceStatus.Ok && !builder.Context.AnalizeDependenciesOnly) { return; } actualArguments[i] = dependency.Value; } foreach (var d in builder.Configuration.ImplicitDependencies) { var dependency = ResolveCore(ServiceName.Parse(d.Type, d.Contracts), false, null, builder.Context) .AsDependency(containerContext, null, false); dependency.Comment = "implicit"; builder.AddDependency(dependency, false); if (dependency.ContainerService != null) { builder.UnionUsedContracts(dependency.ContainerService); } if (builder.Status != ServiceStatus.Ok) { return; } } builder.EndResolveDependencies(); if (builder.Context.AnalizeDependenciesOnly) { return; } var dependenciesResolvedByArguments = builder.Arguments == null ? null : builder.Arguments.GetUsed(); List <string> unusedConfigurationKeys = null; foreach (var k in builder.Configuration.GetUnusedDependencyKeys()) { var resolvedByArguments = dependenciesResolvedByArguments != null && k.name != null && dependenciesResolvedByArguments.Contains(k.name); if (resolvedByArguments) { continue; } if (unusedConfigurationKeys == null) { unusedConfigurationKeys = new List <string>(); } unusedConfigurationKeys.Add(k.ToString()); } if (unusedConfigurationKeys != null) { builder.SetError(string.Format("unused dependency configurations [{0}]", unusedConfigurationKeys.JoinStrings(","))); return; } if (hasServiceNameParameters) { for (var i = 0; i < formalParameters.Length; i++) { if (formalParameters[i].ParameterType == typeof(ServiceName)) { actualArguments[i] = builder.GetFinalName(); } } } if (builder.CreateNew || builder.DeclaredContracts.Length == builder.FinalUsedContracts.Length) { builder.CreateInstanceBy(CallTarget.M(constructor.value, null, actualArguments), true); if (builder.CreateNew && builder.Arguments == null) { var compiledConstructor = constructor.value.Compile(); factoryCache.TryAdd(builder.GetFinalName(), () => { var instance = compiledConstructor(null, actualArguments); var component = instance as IInitializable; if (component != null) { component.Initialize(); } return(instance); }); } return; } var serviceForUsedContractsId = instanceCache.GetOrAdd(builder.GetFinalName(), createId); var acquireResult = serviceForUsedContractsId.AcquireInstantiateLock(); if (acquireResult.acquired) { builder.CreateInstanceBy(CallTarget.M(constructor.value, null, actualArguments), true); serviceForUsedContractsId.ReleaseInstantiateLock(builder.Context.AnalizeDependenciesOnly ? null : builder.GetService()); } else { builder.Reuse(acquireResult.alreadyConstructedService); } }