> For the complete documentation index, see [llms.txt](https://docs.umbraco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umbraco.com/umbraco-cms/13.latest/reference/plugins/creating-resolvers.md).

# Creating Resolvers

*A Resolver should be created for any plugin type. Resolvers are the standard way to retrieve/create/register plugin types.*

## Creating a single object resolver

As an example, we'll create a resolver to resolve an application error logger:

```csharp
/// <summary>
/// An object resolver to return the IErrorLogger
/// </summary>
public class ErrorLoggerResolver : SingleObjectResolverBase<ErrorLoggerResolver, IErrorLogger>
{
    internal ContentStoreResolver(IErrorLogger errorLogger)
        : base(errorLogger)
    {
    }

    /// <summary>
    /// Can be used by developers at runtime to set their IErrorLogger at app startup
    /// </summary>
    /// <param name="contentStore"></param>
    public void SetErrorLogger(IErrorLogger errorLogger)
    {
        Value = errorLogger;
    }

    /// <summary>
    /// Returns the IErrorLogger
    /// </summary>
    public IErrorLogger ErrorLogger
    {
        get { return Value; }
    }
}
```

All you need to do is inherit from `Umbraco.Core.ObjectResolution.SingleObjectResolverBase<TResolver, TResolved>` and then add whatever constructors, properties and methods you would like to expose.

In the example above we have a constructor that accepts a default `IErrorLogger`. Normally in Umbraco this resolver will be constructed in a `IBootManager` with a default object. The we expose a method to allow developers to change to a custom `IErrorLogger` at runtime called `SetErrorLogger`. Then we create a property to expose the `IErrorLogger` called ErrorLogger.

Example:

```csharp
// get the error logger
IErrorLogger logger = ErrorLoggerResolver.Current.ErrorLogger;

// set the error logger (can only be done during application startup)
ErrorLoggerResolver.Current.SetErrorLogger(new MyCustomErrorLogger("../my-file-path"));
```

## Creating a multiple object resolver

Creating a multiple object resolver is similar. As an example we'll create a LanguageConvertersResolver.

{% hint style="info" %}
The naming convention for multiple objects resolvers are plural: We've named this LanguageConverter**s**Resolver with a pluralized 'Converters' to denote that this resolver returns multiple objects
{% endhint %}

```csharp
public sealed class LanguageConvertersResolver : ManyObjectsResolverBase<LanguageConvertersResolver, ILanguageConverter>
{
    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="converters"></param>
    internal LanguageConvertersResolver(IEnumerable<Type> converters)
        : base(converters)
    {
    }

    /// <summary>
    /// Return the converters
    /// </summary>
    public IEnumerable<ILanguageConverter> Converters
    {
        get { return Values; }
    }

}
```

When creating a multiple object resolver you need to decide what lifetime scope the objects created and returned will have which is defined in the constructor created. The default constructor of the `ManyObjectsResolverBase` specifies that the objects created will have an Application based lifetime scope which means the objects will be singletons only one instance of each one will exist for the lifetime of the application. There are 3 lifetime scopes that can be specified:

* ObjectLifetimeScope.Application
  * One instance of each object will be created for the entire lifetime of the application (singleton)
* ObjectLifetimeScope.Transient
  * A new instance of each object will be created each time the 'Values' collection is accessed
* ObjectLifetimeScope.HttpRequest
  * One instance of each object will be created for the lifetime of the current http request


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.umbraco.com/umbraco-cms/13.latest/reference/plugins/creating-resolvers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
