I posted before about trying to use the dynamic web api controllers with WPF/Xamarin but I don't think I got a response yet.
I thought that I could host my webapi module in an Owin self hosting console project.
So the console program depends on my web api module
[DependsOn(typeof(ReadyCareWebApiModule))] class Program { static void Main(string[] args) { } } I came up with this so far for the statup mehod.
using Abp; using Abp.Modules; using Abp.WebApi.Configuration; // Add the following usings: using Owin; using System.Web.Http;
namespace ReadyCare.Owin.WebApi.Host { public class Startup : AbpModule { // This method is required by Katana: public void Configuration(IAppBuilder app) { AbpBootstrapper bootstrapper = new AbpBootstrapper();
bootstrapper.Initialize();
WindsorDependencyResolver windsorDependencyResolver = new WindsorDependencyResolver();
windsorDependencyResolver.IocManager = this.IocManager;
var httpConfiguration = IocManager.Resolve<IAbpWebApiModuleConfiguration>().HttpConfiguration;
httpConfiguration.DependencyResolver = windsorDependencyResolver;
// Use the extension method provided by the WebApi.Owin library:
app.UseWebApi(httpConfiguration);
}
}
}
Where the The WindsorDependencyResolver will be SOMETHING like this, based on another post you made?
public class WindsorDependencyResolver : IDependencyResolver { public IIocManager IocManager { get; set; } public override object GetService(Type serviceType) { return IocManager.IocContainer.Kernel.HasComponent(serviceType) ? IocManager.IocContainer.Resolve(serviceType) : base.GetService(serviceType); }
public override IEnumerable<object> GetServices(Type serviceType)
{
return IocManager.IocContainer.Kernel.HasComponent(serviceType) ? IocManager.IocContainer.ResolveAll(serviceType).Cast<object>() : base.GetServices(serviceType);
}
}
Maybe I need some more support, happy to discuss options. Best Regards, Alistair
1 Answer(s)
-
0
I am actually trying to use a Windsor IHttpControllerActivator now.
using Abp.Modules; using Castle.Windsor; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Web.Http.Controllers; using System.Web.Http.Dispatcher;
namespace ReadyCare.Owin.WebApi.Host { public class WindsorCompositionRoot : AbpModule, IHttpControllerActivator { //private readonly IWindsorContainer container;
public WindsorCompositionRoot() //public WindsorCompositionRoot(IWindsorContainer container) { //this.container = container; } public IHttpController Create( HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { var controller = (IHttpController)this.IocManager.IocContainer.Resolve(controllerType); request.RegisterForDispose( new Release( () => this.IocManager.IocContainer.Release(controller))); return controller; } private class Release : IDisposable { private readonly Action release; public Release(Action release) { this.release = release; } public void Dispose() { this.release(); } } }
}
And the startup is now
using Abp; using Abp.Modules; using Abp.WebApi.Configuration; // Add the following usings: using Owin; using ReadyCare.WebApi; using System.Web.Http; using System.Web.Http.Dispatcher;
namespace ReadyCare.Owin.WebApi.Host { [DependsOn(typeof(ReadyCareWebApiModule))] public class Startup : AbpModule { // This method is required by Katana: public new void Configuration(IAppBuilder app) { AbpBootstrapper bootstrapper = new AbpBootstrapper();
bootstrapper.Initialize(); GlobalConfiguration.Configuration.Services.Replace( typeof(IHttpControllerActivator), new WindsorCompositionRoot()); var httpConfiguration = IocManager.Resolve<IAbpWebApiModuleConfiguration>().HttpConfiguration; //httpConfiguration.DependencyResolver = windsorDependencyResolver; // Use the extension method provided by the WebApi.Owin library: app.UseWebApi(httpConfiguration); } }
}
But I get a "Object reference not set to an instance of an object." when the startup is called in the main
using Abp.Modules; using ReadyCare.WebApi; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Owin.Hosting;
namespace ReadyCare.Owin.WebApi.Host {
class Program { static void Main(string[] args) { string baseUri = "http://localhost:8080"; Console.WriteLine("Starting web Server..."); try { WebApp.Start<Startup>(baseUri); } catch(Exception ex) { string msg = ex.GetBaseException().Message; } Console.WriteLine("Server running at {0} - press Enter to quit. ", baseUri); Console.ReadLine(); } }
}
Note that my ReadyCareWebApiModule is intialising fine. like this
using System.Reflection; using Abp.Application.Services; using Abp.Modules; using Abp.WebApi; using Abp.WebApi.Controllers.Dynamic.Builders; using ReadyCare.Application; using ReadCare.ViewModels;
namespace ReadyCare.WebApi { [DependsOn(typeof(AbpWebApiModule), typeof(ReadyCareApplicationModule))] public class ReadyCareWebApiModule : AbpModule { public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
DynamicApiControllerBuilder .For<IImageApplicationService<PatientBodyImageViewModel>>("telstra/readycare/ImageApplicationService") .WithConventionalVerbs() .Build(); //DynamicApiControllerBuilder // .ForAll<IApplicationService>(typeof(ReadyCareApplicationModule).Assembly, "telstra/readycare") // .WithConventionalVerbs() // .Build(); } }
}
Where I am using a generic for the ImageApplicationService as the DTOs are viewmodels for Xamarin/WPF and simple dtos for Web apps.