Q:

Cache instance per constructor arguments

I have Player and CharacterSpawner which takes IPlayer in its constructor. 
    class CharacterSpawner : ICharacterSpawner
    {
        public CharacterSpawner(IPlayer player, SomeDep dep)
        {
            // ...
        }

        public void SpawnNext()
        {
            // ...
        }
    }

In some parts of my app I want to Resolve ICharacterSpawner for particular IPlayer.  I want to cache ICharacterSpawner instances so that only one is created per IPlayer. How can I do that with Autofac?
update
Suggested existing answer is not about AutoFac but about Castle instead. I need to use Autofac for my project.

A:

There is no built in support in Autofac that will suit your needs but I can see a solution by registering a lambda expression that will choose the ICharacterSpawner from a Dictionary. The key is to cast the provided context to a IInstanceLookup to retrieve the provided IPlayer 
Here is a sample code that works for your case. I use IService and IOwner that are defined as : 
interface IService
{
    String Code { get; }
}
class MyService : IService
{
    public MyService() : this(DateTime.Now.Ticks.ToString())
    { }
    public MyService(String code)
    {
        this.Code = code;
    }
    public String Code { get; }
}

interface IOwner { }
class Owner : IOwner
{
    public Owner(IService service)
    {
        Console.WriteLine($"new owner for service {service.Code}");
    }
}

And my registration looks like : 
ContainerBuilder builder = new ContainerBuilder();
var owners = new ConcurrentDictionary<IService, IOwner>();
builder.RegisterType<MyService>().As<IService>().OnRelease(o =>
{
    IOwner owner;
    owners.TryRemove(o, out owner);
});
builder.RegisterType<Owner>().Named<IOwner>("newOwner");
builder.Register(c =>
{
    IEnumerable<Parameter> parameters = Enumerable.Empty<Parameter>();
    IInstanceLookup instanceLookup = c as IInstanceLookup;
    if (instanceLookup != null)
    {
        parameters = instanceLookup.Parameters;
    }

    IService service = parameters.OfType<TypedParameter>()
                                 .Where(tp => tp.Type == typeof(IService))
                                 .Select(tp => tp.Value)
                                 .OfType<IService>()
                                 .FirstOrDefault();
    if (service == null)
    {
        service = c.Resolve<IService>();
        parameters = parameters.Concat(new Parameter[] {
            TypedParameter.From<IService>(service)
        });
    }

    IOwner owner = owners.GetOrAdd(service, _ =>
        c.ResolveNamed<IOwner>("newOwner", parameters)
    );

    return owner;
}).As<IOwner>();

IContainer container = builder.Build();

Then you will be able to do that
IService service1 = new MyService("service1");
IService service2 = new MyService("service2");

container.Resolve<IOwner>(TypedParameter.From<IService>(service1));
container.Resolve<IOwner>(TypedParameter.From<IService>(service1));
container.Resolve<IOwner>(TypedParameter.From<IService>(service2));

