tldr; Get the code from my Github repository here: https://github.com/devdaves/ExampleWebApi
Start a new ASP.NET Web Application
Select the Empty template. Don't check any of the core references (Web Forms, MVC or Web API).
Once the project is ready to go, open the package manager console and run the following commands to install the necessary nuget packages.
- install-package Microsoft.AspNet.WebApi.Owin
- install-package Microsoft.Owin.Host.SystemWeb
- install-package Castle.Windsor
Open the web.config and add the following code:
<add key="owin:AutomaticAppStartup" value="true" />
</appSettings>
In the Solution Explorer create a Startup class at the root of the site with the following code:
{
public void Configuration(IAppBuilder appBuilder)
{
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
appBuilder.UseWebApi(config);
}
}
In the Solution Explorer create a Models folder and inside the Models folder create a Contact class with the following code:
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In the Solution Explorer create a Controllers folder and inside the Controllers folder create a Web API controller called ContactsController with the following code:
{
[HttpGet]
[Route("contacts")]
public IHttpActionResult Get()
{
return Ok(new Contact(){FirstName = "Donald", LastName = "Duck"});
}
}
At this point you have enough to run the application and should be able to go to http://localhost:####/contacts in your browser and see the contact returned.
Now its time to add Windsor. In the Solution Explorer add a new folder called Windsor. Create a new class called WindsorDependencyScope with the following code:
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t)
? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t)
.Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
Add a new class to the Windsor folder called WindsorHttpDependencyResolver with the following code:
{
private readonly IWindsorContainer _container;
public WindsorHttpDependencyResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t)
? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t)
.Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
In the Windsor folder create a new folder called Installers. Create a new class in the Installers folder called ControllerInstaller with the following code:
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.Pick().If(t => t.Name.EndsWith("Controller"))
.Configure(configurer => configurer.Named(configurer.Implementation.Name))
.LifestylePerWebRequest());
}
}
Create another new class in the Windsor/Installers folder called DefaultInstaller with the following code:
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.Pick()
.WithServiceDefaultInterfaces()
.Configure(c => c.LifestyleTransient()));
}
}
Now we need to make the final changes to the Startup class we created in the root of the site. Make it look like this:
{
public void Configuration(IAppBuilder appBuilder)
{
var container = new WindsorContainer().Install(
new ControllerInstaller(),
new DefaultInstaller());
var httpDependencyResolver = new WindsorHttpDependencyResolver(container);
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.DependencyResolver = httpDependencyResolver;
appBuilder.UseWebApi(config);
}
}
Now that Windsor is setup lets add a contact repository and add that as a dependency to the controller so we can see Windsor in action.
In the Solution Explorer add a folder called Repository. In the Repository folder add a new interface called IContactsRepository with the following code:
{
Contact GetContact();
}
Add a class called ContactsRepository to the Repository folder with the following code:
{
public Contact GetContact()
{
return new Contact(){FirstName = "Donald", LastName = "Duck"};
}
}
Now lets go add the dependency to the ContactsController, make the ContactsController code look like this:
{
private IContactsRepository repository;
public ContactsController(IContactsRepository repository)
{
this.repository = repository;
}
[HttpGet]
[Route("contacts")]
public IHttpActionResult Get()
{
return Ok(this.repository.GetContact());
}
}
That should be it. Running the site now everything should work.
Hi Dave,
ReplyDeleteWhen I try to request accordig to your devepolment, I take an error "An error occurred when trying to create a controller of type 'ContactsController'. Make sure that the controller has a parameterless public constructor.""
Could you share with me . Is it available to share this project in github.?
Thanks
Hi, I am so sorry, I couldn't see although you share :)
ReplyDeleteno problem :)
DeleteBig thanks for this great example!
ReplyDelete