//
// StatefulRepository.cs
//
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using NosSmooth.Core.Client;
namespace NosSmooth.Core.Stateful;
///
/// Repository holding all the stateful entities for various NosTale clients.
///
public class StatefulRepository
{
private readonly ConcurrentDictionary> _statefulEntities;
///
/// Initializes a new instance of the class.
///
public StatefulRepository()
{
_statefulEntities = new ConcurrentDictionary>();
}
///
/// Remove items of the given client.
///
/// The client to remove.
public void Remove(INostaleClient client)
{
_statefulEntities.Remove(client, out _);
}
///
/// Set entity of the given type to the given client.
///
///
/// If the entity is not set manually, there will be an attempt to create an instance.
///
/// The nostale client.
/// The entity.
/// The type of the entity.
public void SetEntity(INostaleClient client, TEntity entity)
where TEntity : notnull
{
_statefulEntities.TryAdd(client, new ConcurrentDictionary());
var values = _statefulEntities[client];
values.AddOrUpdate(typeof(TEntity), (k) => entity, (k, v) => entity);
}
///
/// Get an entity for the given client and type.
///
/// The service provider.
/// The NosTale client.
/// The type of the stateful entity to obtain.
/// The obtained entity.
public object GetEntity(IServiceProvider services, INostaleClient client, Type statefulEntityType)
{
var dict = _statefulEntities.AddOrUpdate
(
client,
_ =>
{
var objectDictionary = new ConcurrentDictionary();
objectDictionary.TryAdd
(statefulEntityType, ActivatorUtilities.CreateInstance(services, statefulEntityType));
return objectDictionary;
},
(_, objectDictionary) =>
{
if (!objectDictionary.ContainsKey(statefulEntityType))
{
objectDictionary.TryAdd
(statefulEntityType, ActivatorUtilities.CreateInstance(services, statefulEntityType));
}
return objectDictionary;
}
);
return dict[statefulEntityType];
}
}