> 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
