Dependency injection for ASP.NET Web API action method parameters

前端 未结 2 1164
渐次进展
渐次进展 2021-02-06 04:00

I am working on an ASP.NET Web API project in C# for a JSON interface to a mobile application. My idea was to create interfaces for all requests and then only use these interfac

相关标签:
2条回答
  • 2021-02-06 04:12

    This is what I came up with now and it works.

    I decided to create a custom formatter which does the unity calls and forwards all further operations to another formatter using the resolved type. It looks like a lot of code, but that is only because all the methods need to be overwritten so the type can always be resolved.

    public class UnityFormatter : MediaTypeFormatter
    {
        private MediaTypeFormatter formatter;
    
        private IUnityContainer container;
    
        public UnityFormatter(MediaTypeFormatter formatter, IUnityContainer container)
        {
            this.formatter = formatter;
            this.container = container;
    
            foreach (var supportedMediaType in this.formatter.SupportedMediaTypes)
            {
                this.SupportedMediaTypes.Add(supportedMediaType);
            }
    
            foreach (var supportedEncoding in this.formatter.SupportedEncodings)
            {
                this.SupportedEncodings.Add(supportedEncoding);
            }
    
            foreach (var mediaTypeMapping in this.MediaTypeMappings)
            {
                this.MediaTypeMappings.Add(mediaTypeMapping);
            }
    
            this.RequiredMemberSelector = this.formatter.RequiredMemberSelector;
        }
    
        private Type ResolveType(Type type)
        {
            return this.container.Registrations.Where(n => n.RegisteredType == type).Select(n => n.MappedToType).FirstOrDefault() ?? type;
        }
    
        public override bool CanReadType(Type type)
        {
            return this.formatter.CanReadType(this.ResolveType(type));
        }
    
        public override bool CanWriteType(Type type)
        {
            return this.formatter.CanWriteType(this.ResolveType(type));
        }
    
        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {
            return this.formatter.GetPerRequestFormatterInstance(this.ResolveType(type), request, mediaType);
        }
    
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return this.formatter.ReadFromStreamAsync(this.ResolveType(type), readStream, content, formatterLogger);
        }
    
        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            this.formatter.SetDefaultContentHeaders(this.ResolveType(type), headers, mediaType);
        }
    
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            return this.formatter.WriteToStreamAsync(this.ResolveType(type), value, writeStream, content, transportContext);
        }
    }
    

    Finally, register our custom formatter in the application config (Global.asax Application_Start). I chose to replace all current formatters with an instance of my custom one, so I get reflection for all data types.

    // set up unity container, register all types
    UnityContainer container = new UnityContainer();
    container.RegisterType<IApiRegistrationRequest, ApiRegistrationRequest>();
    
    // save existing formatters and remove them from the config
    List<MediaTypeFormatter> formatters = new List<MediaTypeFormatter>(GlobalConfiguration.Configuration.Formatters);
    GlobalConfiguration.Configuration.Formatters.Clear();
    
    // create an instance of our custom formatter for each existing formatter
    foreach (MediaTypeFormatter formatter in formatters)
    {
        GlobalConfiguration.Configuration.Formatters.Add(new UnityFormatter(formatter, container));
    }
    
    0 讨论(0)
  • 2021-02-06 04:20

    I Suggest you Have a look at Service Stack http://www.servicestack.net/

    Its got the same all around design as asp.net-WebApi but it has goodies like IOC baked into it.

    There is a amazing series on service stack at http://pluralsight.com/training/Courses/TableOfContents/service-stack

    0 讨论(0)
提交回复
热议问题