The IoC container

mambrowv edited this page Nov 11, 2016 · 39 revisions

  1. Getting Started

    1. Creating your first project
      1. Create Service from scratch
    2. Your first webservice explained
    3. Example Projects Overview
    4. Learning Resources
  2. Designing APIs

    1. ServiceStack API Design
    2. Designing a REST-ful service with ServiceStack
      1. Simple Customer REST Example
    3. How to design a Message-Based API
    4. Software complexity and role of DTOs
  3. Reference

    1. Order of Operations
    2. The IoC container
    3. Configuration and AppSettings
    4. Metadata page
    5. Rest, SOAP & default endpoints
    6. SOAP support
    7. Routing
    8. Service return types
    9. Customize HTTP Responses
    10. Customize JSON Responses
    11. Plugins
    12. Validation
    13. Error Handling
    14. Security
    15. Debugging
    16. JavaScript Client Library (ss-utils.js)
  4. Clients

    1. Overview
    2. C#/.NET client
      1. .NET Core Clients
    3. Add ServiceStack Reference
      1. C# Add Reference
      2. F# Add Reference
      3. VB.NET Add Reference
      4. Swift Add Reference
      5. Java Add Reference
    4. Silverlight client
    5. JavaScript client
      1. Add TypeScript Reference
    6. Dart Client
    7. MQ Clients
  5. Formats

    1. Overview
    2. JSON/JSV and XML
    3. HTML5 Report Format
    4. CSV Format
    5. MessagePack Format
    6. ProtoBuf Format
  6. View Engines

    1. Razor & Markdown Razor
    2. Markdown Razor
  7. Hosts

    1. IIS
    2. Self-hosting
    3. Messaging
    4. Mono
  8. Security

    1. Authentication
    2. Sessions
    3. Restricting Services
    4. Encrypted Messaging
  9. Advanced

    1. Configuration options
    2. Access HTTP specific features in services
    3. Logging
    4. Serialization/deserialization
    5. Request/response filters
    6. Filter attributes
    7. Concurrency Model
    8. Built-in profiling
    9. Form Hijacking Prevention
    10. Auto-Mapping
    11. HTTP Utils
    12. Dump Utils
    13. Virtual File System
    14. Config API
    15. Physical Project Structure
    16. Modularizing Services
    17. MVC Integration
    18. ServiceStack Integration
    19. Embedded Native Desktop Apps
    20. Auto Batched Requests
    21. Versioning
    22. Multitenancy
  10. Caching

    1. Caching Providers
    2. HTTP Caching
      1. CacheResponse Attribute
      2. Cache Aware Clients
  11. Auto Query

    1. Overview
    2. Why Not OData
    3. AutoQuery RDBMS
    4. AutoQuery Data
      1. AutoQuery Memory
      2. AutoQuery Service
      3. AutoQuery DynamoDB
  12. Server Events

    1. Overview
    2. JavaScript Client
    3. C# Server Events Client
    4. Redis Server Events
  13. Service Gateway

    1. Overview
    2. Service Discovery
  14. Encrypted Messaging

    1. Overview
    2. Encrypted Client
  15. Plugins

    1. Auto Query
    2. Server Sent Events
    3. Swagger API
    4. Postman
    5. Request logger
    6. Sitemaps
    7. Cancellable Requests
    8. CorsFeature
  16. Tests

    1. Testing
    2. HowTo write unit/integration tests
  17. ServiceStackVS

    1. Install ServiceStackVS
    2. Add ServiceStack Reference
    3. TypeScript React Template
      1. React, Redux Chat App
    4. AngularJS App Template
    5. React Desktop Apps
  18. Other Languages

    1. FSharp
      1. Add ServiceStack Reference
    2. VB.NET
      1. Add ServiceStack Reference
    3. Swift
      1. Swift Add Reference
    4. Java
      1. Add ServiceStack Reference
      2. Android Studio & IntelliJ
      3. Eclipse
  19. Amazon Web Services

    1. ServiceStack.Aws
    2. PocoDynamo
    3. AWS Live Demos
    4. Getting Started with AWS
  20. Deployment

    1. Deploy Multiple Sites to single AWS Instance
      1. Simple Deployments to AWS with WebDeploy
    2. Advanced Deployments with OctopusDeploy
  21. Install 3rd Party Products

    1. Redis on Windows
    2. RabbitMQ on Windows
  22. Use Cases

    1. Single Page Apps
      1. HTML, CSS and JS Minifiers
    2. Azure
      1. Connecting to Azure Redis via SSL
    3. Logging
    4. Bundling and Minification
    5. NHibernate
  23. Performance

    1. Real world performance
  24. Other Products

    1. ServiceStack.Redis
    2. ServiceStack.OrmLite
    3. ServiceStack.Text
  25. Future

    1. Roadmap
Clone this wiki locally

This page has moved to

ServiceStack uses a slightly modified version of Funq - which was adopted because of its excellent performance and memory characteristics. ServiceStack's version of Funq has been enhanced with Expression-based Auto-wiring and lifetime Request Scope.

If you so wish, you can still elect to use your favourite IOC by creating an IContainerAdapter for them. See below for examples of adapters for popular IOC's. All ServiceStack's customizable hooks support Auto-wiring out-of-the-box, namely:

For each of these features, dependencies are resolved for all parameters in the constructor that has the most arguments as well as all public properties.

Autowire Registration

You can register dependencies so that all the dependencies are automatically auto-wired. Just like the hooks above, once resolved Funq will create a new instance resolving dependencies for the constructor that has the most arguments as well as all public properties.

public override void Configure(Container container)

There's also support for registration of run-time types with these APIs below:


Custom Registration

Funq also supports custom creation of instances. When used no auto-wiring is performed and it's left up to you to explicitly resolve all your dependencies.

Using Custom Factories

In addition to Auto-wiring Funq allows you to customize the creation of your instance with custom delegates. This is useful when your dependencies require custom configuration. E.g:

container.Register(c => new MyType(c.Resolve<IDependency>(), connectionString));
container.Register<IMyType>(c => new MyType(c.Resolve<IDependency>(), connectionString));
container.Register(c => CreateAndInitializeMyType(c.Resolve<IDependency1>(), c.Resolve<IDependency2>));

Register instances

Other than factories, you can also register custom instances where instead of returning a lambda above you can return an instance:

container.Register(new MyType(c.Resolve<IDependency>(), connectionString));

Note: When using the methods above, the properties and the constructor of the registered type aren't auto-wired (ie the properties and the constructor are not injected). You would need to do that manually like that:

container.Register<T>(c => new Foo(c.Resolve<Some>(), c.Resolve<Other>(), c.Resolve<Dependencies>());

Object lifetime

By default all dependencies registered in Funq have singleton scope, where the same instance is injected into all dependencies. This behaviour can be changed by defining the scope explicitly, which is supported with the following APIs:

container.Register(c => new MyType()).ReusedWithin(ReuseScope.None); 
container.RegisterAutoWiredType(typeof(MyType), ReuseScope.None); 
container.RegisterAutoWiredType(typeof(MyType), typeof(IMyType), ReuseScope.None); 

Supported Lifetime Scopes

  • ReuseScope.Container: Singleton scope (a instance is used per application lifetime)
  • ReuseScope.Request: Request scope (a instance is used per request lifetime)
  • ReuseScope.None: Transient scope (a new instance is created every time)

Advanced Usages

Autowiring Generic Type Definitions

Whilst ServiceStack's IOC doesn't have a native support for registering types based on a generic type definition, it's easy to use the Runtime Type APIs and register them yourself. E.g the example below will register and autowire all types that implement ICommand<T> in the current assembly:

    .Where(x => x.IsOrHasGenericInterfaceTypeOf(typeof(ICommand<>)))
    .Each(x => container.RegisterAutoWiredType(x));

Use another IoC container

public interface IResolver {
    T TryResolve<T>();

public interface IContainerAdapter : IResolver {
    T Resolve<T>();

Example Usage

IKernel kernel = new StandardKernel();
container.Adapter = new NinjectIocAdapter(kernel);

Adding a custom ContainerAdapter allows your services to resolve its dependencies from an alternative IOC, in this way they act like a dependency repository where the services are still registered in Funq but all their dependencies are resolved by the ContainerAdapter specified. Dependencies in constructors are resolved by calling IContainerAdapter.Resolve<T>() whilst public property dependencies are resolved with IContainerAdapter.TryResolve<T>(), the idea is you can have missing constructor dependencies throw an exception whilst you can be more lax about property dependencies, where your service can continue to execute without them (should you wish).

Here are some example how to use some popular IoC containers side-by-side with Funq. Of course you're not only limited to the these IoC containers here:

Use Ninject

public class NinjectIocAdapter : IContainerAdapter
    private readonly IKernel kernel;

    public NinjectIocAdapter(IKernel kernel)
        this.kernel = kernel;

    public T Resolve<T>()
        return this.kernel.Get<T>();

    public T TryResolve<T>()
        return this.kernel.CanResolve<T>() ? this.kernel.Get<T>() : default(T);

Then in the AppHost Configure(Container container) method you need to enable this adapter:

//Create Ninject IoC container
IKernel kernel = new StandardKernel();
//Now register all depedencies to your custom IoC container

//Register Ninject IoC container, so ServiceStack can use it
container.Adapter = new NinjectIocAdapter(kernel);

Use StructureMap

public class StructureMapContainerAdapter : IContainerAdapter
    public T TryResolve<T>()
        return ObjectFactory.TryGetInstance<T>();

    public T Resolve<T>()
        return ObjectFactory.TryGetInstance<T>();

In AppHost Configure:

//Configure User Defined REST Paths
container.Adapter = new StructureMapContainerAdapter();

//Register your dependencies
ObjectFactory.Inject(typeof(IFoo), new Foo());

Note: Due to a behavior of StructureMap, you need your AppHost declare as internal, eg: internal class AppHost : AppHostBase

Use Windsor

// The "ApplicationAssemblyFilter" is a custom class that just helps to 
// automate registration to assemblies which match a particular pattern 
// in the app path
public class ApplicationAssemblyFilter : AssemblyFilter
    public ApplicationAssemblyFilter()
        : base(AppDomain.CurrentDomain.BaseDirectory, Assembly.GetExecutingAssembly().GetName().Name + ".*.dll"){}
public class WindsorContainerAdapter : IContainerAdapter, IDisposable 
    private readonly IWindsorContainer container; 

    public WindsorContainerAdapter() 
        container = new WindsorContainer().Install(FromAssembly.InThisApplication(), 
             FromAssembly.InDirectory(new ApplicationAssemblyFilter())); 

    public T TryResolve<T>() 
       if (container.Kernel.HasComponent(typeof(T)))
          return (T)container.Resolve(typeof(T));

       return default(T); 

    public T Resolve<T>() 
        return container.Resolve<T>(); 

    public void Dispose() 

Use Autofac

public class AutofacIocAdapter : IContainerAdapter
    private readonly IContainer container;

    public AutofacIocAdapter(IContainer container)
        this.container = container;

    public T Resolve<T>()
        return container.Resolve<T>();

    public T TryResolve<T>()
        T result;

        if (container.TryResolve<T>(out result))
            return result;

        return default(T);

Then in the AppHost Configure(Container container) method you need to enable this adapter:

//Create Autofac builder
var builder = new ContainerBuilder();
//Now register all depedencies to your custom IoC container

//Register Autofac IoC container adapter, so ServiceStack can use it
IContainerAdapter adapter = new AutofacIocAdapter(builder.Build());
container.Adapter = adapter;

Use SimpleInjector

public class SimpleInjectorIocAdapter : IContainerAdapter
    private readonly Container container;

    public SimpleInjectorIocAdapter(Container container)
        this.container = container;

    public T Resolve<T>() 
        return (T)this.container.GetInstance(typeof(T));

    public T TryResolve<T>()
        var registration = this.container.GetRegistration(typeof(T));
        return registration == null ? default(T) : (T)registration.GetInstance();

Then in the AppHost Configure(Container container) method you need to enable this adapter:

//Create SimpleInjector IoC container
Container simpleContainer = new Container();
//Now register all depedencies to your simpleContainer 

//Register SimpleInjector IoC container, so ServiceStack can use it
container.Adapter = new SimpleInjectorIocAdapter (simpleContainer);

Use Unity

public class UnityIocAdapter : IContainerAdapter
    private readonly IUnityContainer container;

    public UnityIocAdapter(IUnityContainer container)
        this.container = container;

    public T Resolve<T>()
        return container.Resolve<T>();

    public T TryResolve<T>()
            return container.Resolve<T>();

        return default(T);

Then in the AppHost Configure(Container container) method you need to enable this adapter:

//Create Unity IoC container
var unityContainer = new UnityContainer();
//Now register all depedencies to your custom IoC container

//Register your Unity IoC container, so ServiceStack can use it
container.Adapter = new UnityIocAdapter(unityContainer);

Disposing of your services

The AppHost.Release(instance) method gets called for every resolved service right after it's used. This is the default implementation (which can be overridden):

var iocAdapterReleases = Container.Adapter as IRelease;
if (iocAdapterReleases != null)
    var disposable = instance as IDisposable;
    if (disposable != null)

Which will first try to call your ContainerAdapter if it implements IRelease otherwise if the service is IDisposable it will just dispose of it itself.

So to have resolved services released back into your IOC, implement the IRelease interface on your IContainerAdapter, e.g:

public class WindsorContainerAdapter : IContainerAdapter, IRelease
    private readonly IWindsorContainer _container; 

    public void Release(object instance)

Otherwise you can override default implementation in your AppHost.Release(instance) if you want to do something other than the default implementation.

Community Resources