using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ManagetLinkCollection.LinkStorage;
using ManagetLinkCollection.LinkStorage.Entities;
using ManagetLinkCollection.ObjectLinkStorage.Entities;
namespace ManagetLinkCollection.ObjectLinkStorage
{
/// <summary>
/// Хранилище ссылок на данные.
/// Хранящее данные о множестве объектов, ссылающихся на запись.
/// </summary>
/// <typeparam name="TKey">Ключ</typeparam>
/// <typeparam name="TData">Данные</typeparam>
/// <typeparam name="TObject">Объект, ссылающийся на данные</typeparam>
public class ObjectLinkStorage<TKey, TData, TObject>
where TObject : class
{
#region
public IReadOnlyDictionary<TKey, ILinkItem<TKey, ObjectLinkContainer<TData, TObject>>> Storage { private set; get; }
private readonly LinkStorage<TKey, ObjectLinkContainer<TData, TObject>> _Storage
= new LinkStorage<TKey, ObjectLinkContainer<TData, TObject>>();
#endregion
#region
public ObjectLinkStorage()
{
Storage = _Storage.Storage;
}
#endregion
#region
/// <summary>
/// Добавить ссылку на запись
/// </summary>
/// <param name="key">Ключ</param>
/// <param name="value">Ссылающийся объект</param>
/// <param name="addFactory">Фабрика создания данных записи</param>
/// <param name="updateFactory">Фабрика обновления данных по ключу</param>
public ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> AddLink(
TKey key,
TObject value,
Func<TKey, TData> addFactory,
Func<ILinkItem<TKey, ObjectLinkContainer<TData, TObject>>, TData> updateFactory
)
{
return _Storage.AddLink
(
key,
(_key) =>
CreateBuilder()
.AddObject(value)
.UpdateData(addFactory != null ? addFactory(_key) : default(TData))
.Result(),
(ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> oldValue) =>
CreateBuilder(oldValue.Data)
.AddObject(value)
.UpdateData(updateFactory != null ? updateFactory(oldValue) : oldValue.Data.Data)
.Result()
);
}
public ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> AddLink(
TKey key,
TObject value,
Func<TKey, TData> addFactory
)
{
return AddLink(key, value, addFactory, null);
}
public ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> AddLink(
TKey key,
TObject value,
Func<ILinkItem<TKey, ObjectLinkContainer<TData, TObject>>, TData> updateFactory
)
{
return AddLink(key, value, null, updateFactory);
}
public ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> AddLink(
TKey key,
TObject value
)
{
return AddLink(key, value, null, null);
}
public ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> RemoveLink(
TKey key,
TObject value,
Func<ILinkItem<TKey, ObjectLinkContainer<TData, TObject>>, TData> updateFactory
)
{
return _Storage.RemoveLink(
key,
(ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> oldValue) =>
new ContainerBuilder<TData, TObject>(oldValue.Data)
.RemoveObject(value)
.UpdateData(updateFactory != null ? updateFactory(oldValue) : oldValue.Data.Data)
.Result()
);
}
public ILinkItem<TKey, ObjectLinkContainer<TData, TObject>> RemoveLink(
TKey key,
TObject value
)
{
return RemoveLink(key, value, null);
}
#endregion
private ContainerBuilder<TData, TObject> CreateBuilder(ObjectLinkContainer<TData, TObject> container = null)
{
return
container != null
? new ContainerBuilder<TData, TObject>(container)
: new ContainerBuilder<TData, TObject>();
}
}
}