/// <summary> /// Gets the resource stream. /// </summary> /// <param name="resourceLocation">The resource location.</param> /// <returns>A stream from which to load the resource data.</returns> /// <exception cref="ResourceLoaderInvalidPathException">Resource path was incorrect, or you did not set the build action to Embedded Resource</exception> private static Stream GetResourceStream(EmbeddedResourceAttribute resourceLocation) { return(GetResourceStream(resourceLocation.ResourcePath, resourceLocation.ContainingAssembly)); }
/// <summary> /// Loads the resource from embedded resources and returns it cast to the type of the member that the attribute decorates. /// </summary> /// <param name="targetMemberType">Type of the class member that is decorated by the attribute.</param> /// <param name="resourceAttribute">The attribute which describes where to find the resource.</param> /// <returns>Object of the requested type loaded with the data from the resource.</returns> /// <exception cref="ResourceLoaderInvalidTypeException">The member is of a type not supported by this library.</exception> /// <exception cref="ResourceLoaderException">The requested resource could not be found. Either incorrect path or not marked as embedded resource.</exception> private static object GetResource(Type targetMemberType, EmbeddedResourceAttribute resourceAttribute) { var resourceStream = GetResourceStream(resourceAttribute); // If decorated member is a string, then return the resource as string directly. if (targetMemberType == typeof(string)) { return(GetStringResource(resourceStream)); } // Check for types that can be initialized by a constructor or a given method foreach (var resourceLoadMethod in MethodsToCheck) { MethodBase methodToInvoke = null; object instanceOfType = null; switch (resourceLoadMethod) { case ConstructorLoadedResource _: methodToInvoke = targetMemberType.GetConstructor( BindingFlags.Instance | BindingFlags.Public, new ResourceLoadBinder(), new[] { resourceLoadMethod.ArgumentType }, null); break; case StaticMethodLoadedResource _: methodToInvoke = targetMemberType.GetMethod( resourceLoadMethod.MethodName, BindingFlags.Static | BindingFlags.Public, new ResourceLoadBinder(), new[] { resourceLoadMethod.ArgumentType }, null); break; case InstanceMethodLoadedResource _: // Get default constructor var ctor = targetMemberType.GetConstructor( BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null); if (ctor != null) { // Create instance on which we will invoke the method and ultimately return this instance instanceOfType = ctor.Invoke(null); methodToInvoke = targetMemberType.GetMethod( resourceLoadMethod.MethodName, BindingFlags.Instance | BindingFlags.Public, new ResourceLoadBinder(), new[] { resourceLoadMethod.ArgumentType }, null); } break; } if (methodToInvoke != null) { object invocationResult = null; if (resourceLoadMethod.ArgumentType == typeof(Stream)) { var args = new object[] { resourceStream }; invocationResult = methodToInvoke is ConstructorInfo ctor ? ctor.Invoke(args) : methodToInvoke.Invoke(instanceOfType, args); } else if (resourceLoadMethod.ArgumentType == typeof(StreamReader)) { using (var sr = new StreamReader(resourceStream)) { var args = new object[] { sr }; invocationResult = methodToInvoke is ConstructorInfo ctor ? ctor.Invoke(args) : methodToInvoke.Invoke(instanceOfType, args); } } else if (resourceLoadMethod.ArgumentType == typeof(string)) { var args = new[] { GetStringResource(resourceStream) }; invocationResult = methodToInvoke is ConstructorInfo ctor ? ctor.Invoke(args) : methodToInvoke.Invoke(instanceOfType, args); } return(resourceLoadMethod is InstanceMethodLoadedResource ? instanceOfType : invocationResult); } } // Check registered var plugin = RegisteredPlugins.FirstOrDefault(p => p.Type == targetMemberType); if (plugin != null) { return(plugin.ResourceFormat == ResourceFormat.Stream ? plugin.GetObject(resourceStream) : plugin.GetObject(GetStringResource(resourceStream))); } // Nothing could be found on the target type that we can populate with resource data throw new ResourceLoaderInvalidTypeException(targetMemberType); }