using IpcLibrary.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace IpcLibrary.Services {
///
/// 服务注册器实现
///
public class ServiceRegistry : IServiceRegistry {
private readonly ConcurrentDictionary _services;
private readonly object _lock = new object();
public ServiceRegistry() {
_services = new ConcurrentDictionary();
}
public Task RegisterServiceAsync(string serviceName, T serviceInstance) {
if (string.IsNullOrEmpty(serviceName))
throw new ArgumentException("服务名称不能为空", nameof(serviceName));
if (serviceInstance == null)
throw new ArgumentNullException(nameof(serviceInstance));
var serviceInfo = new ServiceInfo {
ServiceName = serviceName,
ServiceInstance = serviceInstance,
ServiceType = typeof(T),
RegisterTime = DateTime.UtcNow,
Methods = GetServiceMethods(typeof(T))
};
_services.AddOrUpdate(serviceName, serviceInfo, (key, old) => serviceInfo);
return Task.CompletedTask;
}
public Task UnregisterServiceAsync(string serviceName) {
if (string.IsNullOrEmpty(serviceName))
throw new ArgumentException("服务名称不能为空", nameof(serviceName));
_services.TryRemove(serviceName, out _);
return Task.CompletedTask;
}
public object GetService(string serviceName) {
return _services.TryGetValue(serviceName, out var serviceInfo)
? serviceInfo.ServiceInstance
: null;
}
public T GetService(string serviceName) {
var service = GetService(serviceName);
return service is T typedService ? typedService : default(T);
}
public bool IsServiceRegistered(string serviceName) {
return _services.ContainsKey(serviceName);
}
public IReadOnlyList GetRegisteredServices() {
return _services.Keys.ToList();
}
public ServiceInfo GetServiceInfo(string serviceName) {
return _services.TryGetValue(serviceName, out var serviceInfo) ? serviceInfo : null;
}
private Dictionary GetServiceMethods(Type serviceType) {
var methods = new Dictionary();
foreach (var method in serviceType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) {
// 排除Object的基本方法
if (method.DeclaringType == typeof(object))
continue;
var key = GetMethodKey(method);
methods[key] = method;
}
return methods;
}
private string GetMethodKey(MethodInfo method) {
var parameters = method.GetParameters();
var paramTypes = string.Join(",", parameters.Select(p => p.ParameterType.FullName));
return $"{method.Name}({paramTypes})";
}
}
}