Current work Fluent NHibernate
parent
6c4de34920
commit
4b2a01fe58
|
@ -5,20 +5,21 @@ using Tiger.Communication.Messages.Types;
|
||||||
using Tiger.Game.Habbos;
|
using Tiger.Game.Habbos;
|
||||||
using Tiger.Game.Settings;
|
using Tiger.Game.Settings;
|
||||||
using Tiger.Networking.Game.Sessions;
|
using Tiger.Networking.Game.Sessions;
|
||||||
|
using Tiger.Storage;
|
||||||
|
|
||||||
namespace Tiger.Communication.Messages.Incoming.Handshake;
|
namespace Tiger.Communication.Messages.Incoming.Handshake;
|
||||||
|
|
||||||
public class SsoTicketEvent : IMessageEvent
|
public class SsoTicketEvent : IMessageEvent
|
||||||
{
|
{
|
||||||
private readonly IHabboDao _habboDao;
|
private readonly IRepository<Habbo> _habboRepository;
|
||||||
private readonly IGameSessionManager _gameSessionManager;
|
private readonly IGameSessionManager _gameSessionManager;
|
||||||
private readonly ISettingsManager _settingsManager;
|
private readonly ISettingManager _settingManager;
|
||||||
|
|
||||||
public SsoTicketEvent(IHabboDao habboDao, IGameSessionManager gameSessionManager, ISettingsManager settingsManager)
|
public SsoTicketEvent(IRepository<Habbo> habboRepository, IGameSessionManager gameSessionManager, ISettingManager settingManager)
|
||||||
{
|
{
|
||||||
_habboDao = habboDao;
|
_habboRepository = habboRepository;
|
||||||
_gameSessionManager = gameSessionManager;
|
_gameSessionManager = gameSessionManager;
|
||||||
_settingsManager = settingsManager;
|
_settingManager = settingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IncomingHeaders Header => IncomingHeaders.SSoTicketEvent;
|
public IncomingHeaders Header => IncomingHeaders.SSoTicketEvent;
|
||||||
|
@ -33,7 +34,7 @@ public class SsoTicketEvent : IMessageEvent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var habbo = await _habboDao.GetHabboBySsoAsync(sso);
|
var habbo = await _habboRepository.FindOneByAsync(h => h.SsoTicket == sso);
|
||||||
|
|
||||||
if (habbo == null)
|
if (habbo == null)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +46,7 @@ public class SsoTicketEvent : IMessageEvent
|
||||||
|
|
||||||
await gameSession.SendComposerAsync(new AuthenticationOkMessageComposer());
|
await gameSession.SendComposerAsync(new AuthenticationOkMessageComposer());
|
||||||
await gameSession.SendComposerAsync(new HabboBroadcastMessageComposer(
|
await gameSession.SendComposerAsync(new HabboBroadcastMessageComposer(
|
||||||
_settingsManager.GetSetting<string>("welcome.message")
|
_settingManager.GetSetting<string>("welcome.message")
|
||||||
.Replace("{user}", gameSession.Habbo.Username)
|
.Replace("{user}", gameSession.Habbo.Username)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class UserObjectMessageComposer : IMessageComposer
|
||||||
message.AppendInt32(0); // respect points to give
|
message.AppendInt32(0); // respect points to give
|
||||||
message.AppendInt32(0); // scratch to give
|
message.AppendInt32(0); // scratch to give
|
||||||
message.AppendBoolean(false);
|
message.AppendBoolean(false);
|
||||||
message.AppendString(_habbo.LastLogin.ToString(CultureInfo.CurrentCulture));
|
message.AppendString(_habbo.LastLogin?.ToString(CultureInfo.CurrentCulture) ?? string.Empty);
|
||||||
message.AppendBoolean(false); // can change name
|
message.AppendBoolean(false); // can change name
|
||||||
message.AppendBoolean(false); // safety locked
|
message.AppendBoolean(false); // safety locked
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,21 @@
|
||||||
using MySqlConnector;
|
|
||||||
|
|
||||||
namespace Tiger.Game.Habbos;
|
namespace Tiger.Game.Habbos;
|
||||||
|
|
||||||
public class Habbo
|
public class Habbo
|
||||||
{
|
{
|
||||||
public uint Id { get; }
|
public virtual uint Id { get; set; }
|
||||||
public string Username { get; }
|
public virtual string Username { get; set; } = null!;
|
||||||
public string Email { get; }
|
public virtual string Password { get; set; } = null!;
|
||||||
public DateTime AccountCreated { get; }
|
public virtual string Email { get; set; } = null!;
|
||||||
public DateTime LastLogin { get; }
|
public virtual DateTime AccountCreated { get; set; }
|
||||||
public string Motto { get; set; }
|
public virtual DateTime? LastLogin { get; set; }
|
||||||
public string Figure { get; set; }
|
public virtual string Motto { get; set; } = null!;
|
||||||
public string Gender { get; set; }
|
public virtual string Figure { get; set; } = null!;
|
||||||
public byte Rank { get; set; }
|
public virtual string Gender { get; set; } = null!;
|
||||||
public uint Credits { get; set; }
|
public virtual byte Rank { get; set; }
|
||||||
public bool Online { get; set; }
|
public virtual uint Credits { get; set; }
|
||||||
public uint HomeRoom { get; set; }
|
public virtual bool Online { get; set; }
|
||||||
public uint AchievementScore { get; set; }
|
public virtual uint HomeRoom { get; set; }
|
||||||
public uint GroupId { get; set; }
|
public virtual uint AchievementScore { get; set; }
|
||||||
|
public virtual uint? GroupId { get; set; }
|
||||||
public Habbo(MySqlDataReader reader)
|
public virtual string? SsoTicket { get; set; }
|
||||||
{
|
|
||||||
Id = reader.GetUInt32("id");
|
|
||||||
Username = reader.GetString("username");
|
|
||||||
Email = reader.GetString("email");
|
|
||||||
AccountCreated = reader.GetDateTime("account_created");
|
|
||||||
LastLogin = reader.GetDateTime("last_login");
|
|
||||||
Motto = reader.GetString("motto");
|
|
||||||
Figure = reader.GetString("figure");
|
|
||||||
Gender = reader.GetString("gender");
|
|
||||||
Rank = reader.GetByte("rank");
|
|
||||||
Credits = reader.GetUInt32("credits");
|
|
||||||
Online = reader.GetBoolean("online");
|
|
||||||
HomeRoom = reader.GetUInt32("home_room");
|
|
||||||
AchievementScore = reader.GetUInt32("achievement_score");
|
|
||||||
GroupId = reader.GetUInt32("group_id");
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
using Tiger.Storage;
|
|
||||||
|
|
||||||
namespace Tiger.Game.Habbos;
|
|
||||||
|
|
||||||
public class HabboDao : IHabboDao
|
|
||||||
{
|
|
||||||
private readonly IDatabaseHelper _databaseHelper;
|
|
||||||
|
|
||||||
public HabboDao(IDatabaseHelper databaseHelper)
|
|
||||||
{
|
|
||||||
_databaseHelper = databaseHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Habbo?> GetHabboBySsoAsync(string sso)
|
|
||||||
{
|
|
||||||
await using var dbConnection = _databaseHelper.GetConnection();
|
|
||||||
var resultSet =
|
|
||||||
await dbConnection.GetResultSet("SELECT * FROM habbos WHERE sso_ticket = @sso LIMIT 1", ("@sso", sso));
|
|
||||||
if (await resultSet.ReadAsync())
|
|
||||||
{
|
|
||||||
return new Habbo(resultSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
using FluentNHibernate.Mapping;
|
||||||
|
|
||||||
|
namespace Tiger.Game.Habbos;
|
||||||
|
|
||||||
|
public class HabboMap : ClassMap<Habbo>
|
||||||
|
{
|
||||||
|
public HabboMap()
|
||||||
|
{
|
||||||
|
Table("habbos");
|
||||||
|
LazyLoad();
|
||||||
|
Id(h => h.Id).Column("id").GeneratedBy.Identity();
|
||||||
|
Map(h => h.Username).Column("username").Not.Nullable();
|
||||||
|
Map(h => h.Password).Column("password").Not.Nullable();
|
||||||
|
Map(h => h.Email).Column("email").Not.Nullable();
|
||||||
|
Map(h => h.AccountCreated).Column("account_created").Not.Nullable();
|
||||||
|
Map(h => h.LastLogin).Column("last_login").Nullable();
|
||||||
|
Map(h => h.Motto).Column("motto").Not.Nullable();
|
||||||
|
Map(h => h.Figure).Column("figure").Not.Nullable();
|
||||||
|
Map(h => h.Gender).Column("gender").Not.Nullable();
|
||||||
|
Map(h => h.Rank).Column("rank").Not.Nullable();
|
||||||
|
Map(h => h.Credits).Column("credits").Not.Nullable();
|
||||||
|
Map(h => h.Online).Column("online").Not.Nullable();
|
||||||
|
Map(h => h.HomeRoom).Column("home_room").Not.Nullable();
|
||||||
|
Map(h => h.AchievementScore).Column("achievement_score").Not.Nullable();
|
||||||
|
Map(h => h.GroupId).Column("group_id").Nullable();
|
||||||
|
Map(h => h.SsoTicket).Column("sso_ticket").Nullable();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
namespace Tiger.Game.Habbos;
|
|
||||||
|
|
||||||
public interface IHabboDao
|
|
||||||
{
|
|
||||||
Task<Habbo?> GetHabboBySsoAsync(string sso);
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Tiger.Game.Settings;
|
namespace Tiger.Game.Settings;
|
||||||
|
|
||||||
public interface ISettingsManager
|
public interface ISettingManager
|
||||||
{
|
{
|
||||||
Task ReloadSettingsAsync();
|
Task ReloadSettingsAsync();
|
||||||
T GetSetting<T>(string key);
|
T GetSetting<T>(string key);
|
|
@ -1,6 +0,0 @@
|
||||||
namespace Tiger.Game.Settings;
|
|
||||||
|
|
||||||
public interface ISettingsDao
|
|
||||||
{
|
|
||||||
Task<IReadOnlyDictionary<string, object>> GetSettingsAsync();
|
|
||||||
}
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Tiger.Game.Settings;
|
||||||
|
|
||||||
|
public class Setting
|
||||||
|
{
|
||||||
|
public virtual string Key { get; set; } = string.Empty;
|
||||||
|
public virtual string Value { get; set; } = string.Empty;
|
||||||
|
}
|
|
@ -1,23 +1,24 @@
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Tiger.Storage;
|
||||||
|
|
||||||
namespace Tiger.Game.Settings;
|
namespace Tiger.Game.Settings;
|
||||||
|
|
||||||
public class SettingsManager : ISettingsManager
|
public class SettingManager : ISettingManager
|
||||||
{
|
{
|
||||||
private IReadOnlyDictionary<string, object> _settings;
|
private IReadOnlyDictionary<string, string> _settings;
|
||||||
private readonly ISettingsDao _settingsDao;
|
private readonly IRepository<Setting> _settingRepository;
|
||||||
private readonly ILogger<ISettingsManager> _logger;
|
private readonly ILogger<ISettingManager> _logger;
|
||||||
|
|
||||||
public SettingsManager(ISettingsDao settingsDao, ILogger<ISettingsManager> logger)
|
public SettingManager(IRepository<Setting> settingRepository, ILogger<ISettingManager> logger)
|
||||||
{
|
{
|
||||||
_settingsDao = settingsDao;
|
_settingRepository = settingRepository;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_settings = new Dictionary<string, object>();
|
_settings = new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReloadSettingsAsync()
|
public async Task ReloadSettingsAsync()
|
||||||
{
|
{
|
||||||
_settings = await _settingsDao.GetSettingsAsync();
|
_settings = (await _settingRepository.FindByAsync()).ToDictionary(s => s.Key, s => s.Value);
|
||||||
|
|
||||||
_logger.LogInformation("Loaded {Count} settings", _settings.Count);
|
_logger.LogInformation("Loaded {Count} settings", _settings.Count);
|
||||||
}
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// using FluentNHibernate.Mapping;
|
||||||
|
//
|
||||||
|
// namespace Tiger.Game.Settings;
|
||||||
|
//
|
||||||
|
// public class SettingMap : ClassMap<Setting>
|
||||||
|
// {
|
||||||
|
// public SettingMap()
|
||||||
|
// {
|
||||||
|
// Table("settings");
|
||||||
|
// Id(s => s.Key).Column("skey").Not.Nullable();
|
||||||
|
// Map(s => s.Value).Column("value").Not.Nullable();
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -1,27 +0,0 @@
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using Tiger.Storage;
|
|
||||||
|
|
||||||
namespace Tiger.Game.Settings;
|
|
||||||
|
|
||||||
public class SettingsDao : ISettingsDao
|
|
||||||
{
|
|
||||||
private readonly IDatabaseHelper _databaseHelper;
|
|
||||||
|
|
||||||
public SettingsDao(IDatabaseHelper databaseHelper)
|
|
||||||
{
|
|
||||||
_databaseHelper = databaseHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IReadOnlyDictionary<string, object>> GetSettingsAsync()
|
|
||||||
{
|
|
||||||
var settings = new Dictionary<string, object>();
|
|
||||||
await using var dbConnection = _databaseHelper.GetConnection();
|
|
||||||
await using var resultSet = await dbConnection.GetResultSet("SELECT * FROM settings");
|
|
||||||
while (await resultSet.ReadAsync())
|
|
||||||
{
|
|
||||||
settings.Add(resultSet.GetString("skey"), resultSet.GetValue(resultSet.GetOrdinal("value")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ReadOnlyDictionary<string, object>(settings);
|
|
||||||
}
|
|
||||||
}
|
|
10
Program.cs
10
Program.cs
|
@ -29,15 +29,15 @@ collection.AddSingleton<IConfiguration>(configuration);
|
||||||
collection.AddSingleton<IWebSocketServer, WebSocketServer>();
|
collection.AddSingleton<IWebSocketServer, WebSocketServer>();
|
||||||
collection.AddSingleton<IGameSessionManager, GameSessionManager>();
|
collection.AddSingleton<IGameSessionManager, GameSessionManager>();
|
||||||
collection.AddSingleton<IMessageHandler, MessageHandler>();
|
collection.AddSingleton<IMessageHandler, MessageHandler>();
|
||||||
collection.AddSingleton<IDatabaseHelper, DatabaseHelper>();
|
collection.AddSingleton<INhSessionFactory, NhSessionFactory>();
|
||||||
collection.AddSingleton<ISettingsDao, SettingsDao>();
|
collection.AddScoped(serviceProvider => serviceProvider.GetRequiredService<INhSessionFactory>().OpenSession());
|
||||||
collection.AddSingleton<ISettingsManager, SettingsManager>();
|
collection.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
||||||
collection.AddSingleton<IHabboDao, HabboDao>();
|
collection.AddSingleton<ISettingManager, SettingManager>();
|
||||||
collection.RegisterMessageEvents();
|
collection.RegisterMessageEvents();
|
||||||
|
|
||||||
var provider = collection.BuildServiceProvider();
|
var provider = collection.BuildServiceProvider();
|
||||||
|
|
||||||
await provider.GetRequiredService<ISettingsManager>().ReloadSettingsAsync();
|
await provider.GetRequiredService<ISettingManager>().ReloadSettingsAsync();
|
||||||
|
|
||||||
provider.GetRequiredService<IWebSocketServer>().Start($"http://{configuration["Network:Game:Ip"]}:{configuration["Network:Game:Port"]}/");
|
provider.GetRequiredService<IWebSocketServer>().Start($"http://{configuration["Network:Game:Ip"]}:{configuration["Network:Game:Port"]}/");
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
using MySqlConnector;
|
|
||||||
|
|
||||||
namespace Tiger.Storage;
|
|
||||||
|
|
||||||
public class DatabaseConnection : IAsyncDisposable
|
|
||||||
{
|
|
||||||
private readonly MySqlConnection _connection;
|
|
||||||
private readonly MySqlCommand _command;
|
|
||||||
|
|
||||||
public DatabaseConnection(MySqlConnection connection)
|
|
||||||
{
|
|
||||||
_connection = connection;
|
|
||||||
_command = connection.CreateCommand();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<MySqlDataReader> GetResultSet(string query, params (string, object)[] mysqlParams)
|
|
||||||
{
|
|
||||||
await _connection.OpenAsync();
|
|
||||||
|
|
||||||
_command.CommandText = query;
|
|
||||||
|
|
||||||
foreach (var mysqlParam in mysqlParams)
|
|
||||||
{
|
|
||||||
_command.Parameters.AddWithValue(mysqlParam.Item1, mysqlParam.Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
var reader = await _command.ExecuteReaderAsync();
|
|
||||||
_command.Parameters.Clear();
|
|
||||||
return reader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
|
||||||
{
|
|
||||||
await _connection.DisposeAsync();
|
|
||||||
await _command.DisposeAsync();
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
namespace Tiger.Storage;
|
|
||||||
|
|
||||||
public interface IDatabaseHelper
|
|
||||||
{
|
|
||||||
DatabaseConnection GetConnection();
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
using NHibernate;
|
||||||
|
|
||||||
|
namespace Tiger.Storage;
|
||||||
|
|
||||||
|
public interface INhSessionFactory
|
||||||
|
{
|
||||||
|
ISession OpenSession();
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
namespace Tiger.Storage;
|
||||||
|
|
||||||
|
public interface IRepository<T>
|
||||||
|
{
|
||||||
|
Task<T?> FindAsync(object id);
|
||||||
|
Task SaveAsync(T entity);
|
||||||
|
Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>>? expression = null);
|
||||||
|
Task<T?> FindOneByAsync(Expression<Func<T, bool>> expression);
|
||||||
|
}
|
|
@ -1,13 +1,17 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using FluentNHibernate.Cfg;
|
||||||
|
using FluentNHibernate.Cfg.Db;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using MySqlConnector;
|
using MySql.Data.MySqlClient;
|
||||||
|
using NHibernate;
|
||||||
|
|
||||||
namespace Tiger.Storage;
|
namespace Tiger.Storage;
|
||||||
|
|
||||||
public class DatabaseHelper : IDatabaseHelper
|
public class NhSessionFactory : INhSessionFactory
|
||||||
{
|
{
|
||||||
private readonly string _connectionString;
|
private readonly ISessionFactory _sessionFactory;
|
||||||
|
|
||||||
public DatabaseHelper(IConfiguration configuration)
|
public NhSessionFactory(IConfiguration configuration)
|
||||||
{
|
{
|
||||||
var stringBuilder = new MySqlConnectionStringBuilder
|
var stringBuilder = new MySqlConnectionStringBuilder
|
||||||
{
|
{
|
||||||
|
@ -21,11 +25,14 @@ public class DatabaseHelper : IDatabaseHelper
|
||||||
MaximumPoolSize = uint.Parse(configuration["Database:MaxPool"] ?? "15")
|
MaximumPoolSize = uint.Parse(configuration["Database:MaxPool"] ?? "15")
|
||||||
};
|
};
|
||||||
|
|
||||||
_connectionString = stringBuilder.ToString();
|
_sessionFactory = Fluently.Configure()
|
||||||
|
.Database(MySQLConfiguration.Standard.ConnectionString(stringBuilder.ToString()).ShowSql())
|
||||||
|
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
|
||||||
|
.BuildSessionFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatabaseConnection GetConnection()
|
public ISession OpenSession()
|
||||||
{
|
{
|
||||||
return new DatabaseConnection(new MySqlConnection(_connectionString));
|
return _sessionFactory.OpenSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using NHibernate;
|
||||||
|
using NHibernate.Linq;
|
||||||
|
|
||||||
|
namespace Tiger.Storage;
|
||||||
|
|
||||||
|
public class Repository<T> : IRepository<T> where T : class
|
||||||
|
{
|
||||||
|
private readonly ISession _session;
|
||||||
|
|
||||||
|
public Repository(ISession session)
|
||||||
|
{
|
||||||
|
_session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T?> FindAsync(object id)
|
||||||
|
{
|
||||||
|
return await _session.GetAsync<T>(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveAsync(T entity)
|
||||||
|
{
|
||||||
|
await _session.SaveOrUpdateAsync(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>>? expression)
|
||||||
|
{
|
||||||
|
var query = _session.Query<T>();
|
||||||
|
|
||||||
|
if (expression != null)
|
||||||
|
{
|
||||||
|
query = query.Where(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T?> FindOneByAsync(Expression<Func<T, bool>> expression)
|
||||||
|
{
|
||||||
|
return await _session.Query<T>().FirstOrDefaultAsync(expression);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,12 +12,13 @@
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="FluentNHibernate" Version="3.3.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0-rc.1.23419.4" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0-rc.1.23419.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0-rc.1.23419.4" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0-rc.1.23419.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Yaml" Version="2.0.0-preview2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Yaml" Version="2.0.0-preview2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0-rc.1.23419.4" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0-rc.1.23419.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0-rc.1.23419.4" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0-rc.1.23419.4" />
|
||||||
<PackageReference Include="MySqlConnector" Version="2.3.0-beta.3" />
|
<PackageReference Include="MySql.Data" Version="8.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="appsettings.yaml">
|
<None Update="appsettings.yaml">
|
||||||
|
|
Loading…
Reference in New Issue