static InjectableInfo CreateInjectableInfoForParam( Type parentType, ParameterInfo paramInfo) { var injectAttributes = paramInfo.AllAttributes<InjectAttributeBase>().ToList(); Assert.That(injectAttributes.Count <= 1, "Found multiple 'Inject' attributes on type parameter '{0}' of type '{1}'. Parameter should only have one", paramInfo.Name, parentType.Name()); var injectAttr = injectAttributes.SingleOrDefault(); string identifier = null; bool isOptional = false; InjectSources sourceType = InjectSources.Any; if (injectAttr != null) { identifier = injectAttr.Identifier; isOptional = injectAttr.IsOptional; sourceType = injectAttr.SourceType; } bool isOptionalWithADefaultValue = (paramInfo.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; return new InjectableInfo( isOptionalWithADefaultValue || isOptional, identifier, paramInfo.Name, paramInfo.ParameterType, parentType, null, isOptionalWithADefaultValue ? paramInfo.DefaultValue : null, sourceType); }
public SubContainerCreatorByInstaller( DiContainer container, Type installerType) { _installerType = installerType; _container = container; Assert.That(installerType.DerivesFrom<InstallerBase>(), "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); }
public static void BindPriority( DiContainer container, Type tickableType, int priorityCount) { Assert.That(tickableType.DerivesFrom<ITickable>(), "Expected type '{0}' to derive from ITickable", tickableType.Name()); container.Bind<Tuple<Type, int>>().To( Tuple.New(tickableType, priorityCount)).WhenInjectedInto<StandardKernel>(); }
public static void BindPriority( DiContainer container, Type tickableType, int priorityCount) { Assert.That(tickableType.DerivesFrom<IFixedTickable>(), "Expected type '{0}' to derive from IFixedTickable", tickableType.Name()); container.Bind<ModestTree.Util.Tuple<Type, int>>("Fixed").ToInstance( ModestTree.Util.Tuple.New(tickableType, priorityCount)).WhenInjectedInto<TickableManager>(); }
public static void BindPriority( DiContainer container, Type initializableType, int priorityCount) { Assert.That(initializableType.DerivesFrom<IInitializable>(), "Expected type '{0}' to derive from IInitializable", initializableType.Name()); container.Bind<Tuple<Type, int>>().To( Tuple.New(initializableType, priorityCount)).WhenInjectedInto<InitializableHandler>(); }
public TransientProvider(Type concreteType, DiContainer container) { _concreteType = concreteType; var singletonMark = container.SingletonRegistry.TryGetSingletonType(concreteType); if (singletonMark.HasValue) { throw new ZenjectBindException( "Attempted to use 'ToTransient' with the same type ('{0}') that is already marked with '{1}'".Fmt(concreteType.Name(), singletonMark.Value)); } }
public InstanceProvider(Type instanceType, object instance, DiContainer container) { Assert.That(instance == null || instance.GetType().DerivesFromOrEqual(instanceType)); _instance = instance; _instanceType = instanceType; var singletonMark = container.SingletonRegistry.TryGetSingletonType(instanceType); if (singletonMark.HasValue) { throw new ZenjectBindException( "Attempted to use 'ToInstance' with the same type ('{0}') that is already marked with '{1}'".Fmt(instanceType.Name(), singletonMark.Value)); } }
static InjectableInfo CreateForMember(MemberInfo memInfo, Type parentType) { var injectAttributes = memInfo.AllAttributes<InjectAttributeBase>().ToList(); Assert.That(injectAttributes.Count <= 1, "Found multiple 'Inject' attributes on type field '{0}' of type '{1}'. Field should only container one Inject attribute", memInfo.Name, parentType.Name()); var injectAttr = injectAttributes.SingleOrDefault(); string identifier = null; bool isOptional = false; bool localOnly = false; if (injectAttr != null) { identifier = injectAttr.Identifier; isOptional = injectAttr.IsOptional; localOnly = injectAttr.LocalOnly; } Type memberType; Action<object, object> setter; if (memInfo is FieldInfo) { var fieldInfo = (FieldInfo)memInfo; setter = ((object injectable, object value) => fieldInfo.SetValue(injectable, value)); memberType = fieldInfo.FieldType; } else { Assert.That(memInfo is PropertyInfo); var propInfo = (PropertyInfo)memInfo; setter = ((object injectable, object value) => propInfo.SetValue(injectable, value, null)); memberType = propInfo.PropertyType; } return new InjectableInfo( isOptional, identifier, memInfo.Name, memberType, parentType, setter, null, localOnly); }
public GameObjectTransientProviderFromPrefab( Type concreteType, GameObject template, DiContainer container) { // Don't do this because it might be an interface //Assert.That(typeof(T).DerivesFrom<Component>()); _concreteType = concreteType; _template = template; var singletonMark = container.SingletonRegistry.TryGetSingletonType(concreteType); if (singletonMark.HasValue) { throw new ZenjectBindException( "Attempted to use 'ToTransientPrefab' with the same type ('{0}') that is already marked with '{1}'".Fmt(concreteType.Name(), singletonMark.Value)); } }
static InjectableInfo CreateForMember(MemberInfo memInfo, Type parentType) { var injectAttributes = memInfo.AllAttributes<InjectAttribute>().ToList(); var injectOptionalAttributes = memInfo.AllAttributes<InjectOptionalAttribute>().ToList(); string identifier = null; Assert.That(injectAttributes.IsEmpty() || injectOptionalAttributes.IsEmpty(), "Found both 'InjectOptional' and 'Inject' attributes on type field '{0}' of type '{1}'. Field should only have one or the other.", memInfo.Name, parentType.Name()); if (injectAttributes.Any()) { identifier = injectAttributes.Single().Identifier; } else if (injectOptionalAttributes.Any()) { identifier = injectOptionalAttributes.Single().Identifier; } Type memberType; Action<object, object> setter; if (memInfo is FieldInfo) { var fieldInfo = (FieldInfo)memInfo; setter = ((object injectable, object value) => fieldInfo.SetValue(injectable, value)); memberType = fieldInfo.FieldType; } else { Assert.That(memInfo is PropertyInfo); var propInfo = (PropertyInfo)memInfo; setter = ((object injectable, object value) => propInfo.SetValue(injectable, value, null)); memberType = propInfo.PropertyType; } return new InjectableInfo( injectOptionalAttributes.Any(), identifier, memInfo.Name, memberType, parentType, setter, null); }
/// <summary> /// Gets the name of the type. /// Recursive processing of generic constraints and parameters. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> private static string GetTypeName(Type type) { #if NETFX_CORE if (!type.IsGenericType()) #else if (!type.IsGenericType) #endif { return type.FullName; } else // generic type { var sb = new StringBuilder(); if (!string.IsNullOrEmpty(type.Namespace)) sb.Append(type.Namespace + "."); #if NETFX_CORE var typeName = type.Name(); #else var typeName = type.Name; #endif sb.Append(typeName.Replace("`1", "")); foreach (var t in type.GetGenericArguments()) { sb.Append("-"); #if NETFX_CORE if (t.IsGenericType()) #else if (t.IsGenericType) #endif sb.Append(GetTypeName(t)); else sb.Append(t.FullName); sb.Append("-"); } return sb.ToString(); } }
static InjectableInfo CreateInjectableInfoForParam( Type parentType, ParameterInfo paramInfo) { var injectAttributes = paramInfo.AllAttributes<InjectAttribute>().ToList(); var injectOptionalAttributes = paramInfo.AllAttributes<InjectOptionalAttribute>().ToList(); string identifier = null; Assert.That(injectAttributes.IsEmpty() || injectOptionalAttributes.IsEmpty(), "Found both 'InjectOptional' and 'Inject' attributes on type parameter '{0}' of type '{1}'. Parameter should only have one or the other.", paramInfo.Name, parentType.Name()); if (injectAttributes.Any()) { identifier = injectAttributes.Single().Identifier; } else if (injectOptionalAttributes.Any()) { identifier = injectOptionalAttributes.Single().Identifier; } bool isOptionalWithADefaultValue = (paramInfo.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; return new InjectableInfo( isOptionalWithADefaultValue || injectOptionalAttributes.Any(), identifier, paramInfo.Name, paramInfo.ParameterType, parentType, null, isOptionalWithADefaultValue ? paramInfo.DefaultValue : null); }
public static IEnumerable<ZenjectResolveException> ValidateObjectGraph( DiContainer container, Type concreteType, InjectContext currentContext, params Type[] extras) { var typeInfo = TypeAnalyzer.GetInfo(concreteType); var extrasList = extras.ToList(); foreach (var dependInfo in typeInfo.AllInjectables) { Assert.IsEqual(dependInfo.ObjectType, concreteType); if (TryTakingFromExtras(dependInfo.MemberType, extrasList)) { continue; } var context = dependInfo.CreateInjectContext(container, currentContext, null); foreach (var error in ValidateContract(container, context)) { yield return error; } } if (!extrasList.IsEmpty()) { yield return new ZenjectResolveException( "Found unnecessary extra parameters passed when injecting into '{0}' with types '{1}'. \nObject graph:\n{2}" .Fmt(concreteType.Name(), String.Join(",", extrasList.Select(x => x.Name()).ToArray()), currentContext.GetObjectGraphString())); } }
public static IEnumerable<ZenjectResolveException> ValidateContract( DiContainer container, Type contractType, InjectContext context, bool isOptional) { var matches = container.GetProviderMatches(contractType, context); if (matches.IsLength(1)) { foreach (var error in matches.Single().ValidateBinding(contractType, context)) { yield return error; } } else { if (ReflectionUtil.IsGenericList(contractType)) { var subType = contractType.GetGenericArguments().Single(); matches = container.GetProviderMatches(subType, context); if (matches.IsEmpty()) { if (!isOptional) { if (container.FallbackProvider != null) { foreach (var error in container.FallbackProvider.ValidateBinding(contractType, context)) { yield return error; } } else { yield return new ZenjectResolveException( "Could not find dependency with type 'List<{0}>'{1}. If the empty list is also valid, you can allow this by using the [InjectOptional] attribute.' \nObject graph:\n{2}" .With( subType.Name(), (context.EnclosingType == null ? "" : " when injecting into '{0}'".With(context.EnclosingType.Name())), DiContainer.GetCurrentObjectGraph())); } } } else { foreach (var match in matches) { foreach (var error in match.ValidateBinding(contractType, context)) { yield return error; } } } } else { if (!isOptional) { if (matches.IsEmpty()) { if (container.FallbackProvider != null) { foreach (var error in container.FallbackProvider.ValidateBinding(contractType, context)) { yield return error; } } else { yield return new ZenjectResolveException( "Could not find required dependency with type '{0}'{1} \nObject graph:\n{2}" .With( contractType.Name(), (context.EnclosingType == null ? "" : " when injecting into '{0}'".With(context.EnclosingType.Name())), DiContainer.GetCurrentObjectGraph())); } } else { yield return new ZenjectResolveException( "Found multiple matches when only one was expected for dependency with type '{0}'{1} \nObject graph:\n{2}" .With( contractType.Name(), (context.EnclosingType == null ? "" : " when injecting into '{0}'".With(context.EnclosingType.Name())), DiContainer.GetCurrentObjectGraph())); } } } } }
public IEnumerable<ZenjectResolveException> ValidateBinding( Type componentType, InjectContext context) { if (!ContainsComponent(componentType)) { yield return new ZenjectResolveException( "Could not find component of type '{0}' in prefab with resource path '{1}' \nObject graph:\n{2}" .Fmt(componentType.Name(), _id.ResourcePath, context.GetObjectGraphString())); yield break; } // In most cases componentType will be a MonoBehaviour but we also want to allow interfaces // And in that case we can't validate it if (!componentType.IsAbstract) { // Note that we always want to cache _container instead of using context.Container // since for singletons, the container they are accessed from should not determine // the container they are instantiated with // Transients can do that but not singletons foreach (var err in _container.ValidateObjectGraph(componentType, context)) { yield return err; } } }
private static string GetDisplayName(object instance, string name, Type type) { string text = instance == null ? null : PlatformExtensions.TryGetValue(instance, "Text"); return $"{name} ({type.Name}{(string.IsNullOrEmpty(text) ? "" : ", " + text)})"; }
static string GetFormattedTypeName(Type type) { var str = type.Name(); // GraphViz does not read names with <, >, or . characters so replace them str = str.Replace(">", "_"); str = str.Replace("<", "_"); str = str.Replace(".", "_"); return str; }