// // 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]; } }