C# 在类中使用反射循环字段并在接口上调用函数
我试图使用反射在类XmlSerialization中循环我的IRepository字段。我无法在foreach循环中定义IRepository,而是尝试使用var。但是我无法调用IRepository.Save,不知何故,我需要在foreach循环中过滤通用IRepository 无法从用法推断方法“Fle.SQLServer.XmlFiles.Notifier.xmlsialization.Save(Fle.SQLServer.Core.Services.IRepository)”的类型参数。尝试显式指定类型参数 我理解我的问题,但不能解决它 我想在XmlSerialization上循环我的IRepository字段并调用save,而不调用类中的每个字段C# 在类中使用反射循环字段并在接口上调用函数,c#,reflection,C#,Reflection,我试图使用反射在类XmlSerialization中循环我的IRepository字段。我无法在foreach循环中定义IRepository,而是尝试使用var。但是我无法调用IRepository.Save,不知何故,我需要在foreach循环中过滤通用IRepository 无法从用法推断方法“Fle.SQLServer.XmlFiles.Notifier.xmlsialization.Save(Fle.SQLServer.Core.Services.IRepository)”的类型参数。
using Fle.SQLServer.Core.Model;
using Fle.SQLServer.Core.Services;
namespace Fle.SQLServer.XmlFiles.Notifier
{
public class XmlSerialization : INotifier
{
private readonly IRepository<BackupDeviceLocationData> _repositoryBackupDeviceLocation;
private readonly IRepository<BackupHistoryData> _repositoryBackupHistory;
private readonly IRepository<DatabaseSizesData> _repositoryDatabaseSizes;
private readonly IRepository<DiskSystemData> _repositoryDiskSystem;
private readonly IRepository<FailedDatabaseJobsData> _repositoryFailedDatabaseJobs;
private readonly IRepository<DatabaseReplicationData> _repositoryDatabaseReplication;
private readonly IRepository<DatabaseLongRunningJobData> _repositoryDatabaseLongRunningJob;
private readonly IRepository<DatabaseSystemData> _repositoryDatabaseSystem;
private readonly IRepository<DiskBackupData> _repositoryDiskBackup;
private readonly IRepository<SqlServerAgentEventLogData> _repositorySqlServerAgentEventLog;
private readonly IRepository<SqlServerEventLogData> _repositorySqlEventLog;
private readonly IRepository<DatabaseOwnerData> _repositoryDatabaseOwner;
private readonly IRepository<RecoveryModelData> _repositoryRecoveryModel;
private readonly IRepository<BelongToSystemData> _repositoryBelongToSystem;
public XmlSerialization(IRepository<BackupDeviceLocationData> repositoryBackupDeviceLocation,
IRepository<BackupHistoryData> repositoryBackupHistory,
IRepository<DatabaseSizesData> repositoryDatabaseSizes,
IRepository<DiskSystemData> repositoryDiskSystem,
IRepository<FailedDatabaseJobsData> repositoryFailedDatabaseJobs,
IRepository<DatabaseReplicationData> repositoryDatabaseReplication,
IRepository<DatabaseLongRunningJobData> repositoryDatabaseLongRunningJob,
IRepository<DatabaseSystemData> repositoryDatabaseSystem,
IRepository<DiskBackupData> repositoryDiskBackup,
IRepository<SqlServerAgentEventLogData> repositorySqlServerAgentEventLog,
IRepository<SqlServerEventLogData> repositorySqlEventLog,
IRepository<DatabaseOwnerData> repositoryDatabaseOwner,
IRepository<RecoveryModelData> repositoryRecoveryModel,
IRepository<BelongToSystemData> repositoryBelongToSystem)
{
_repositoryBackupDeviceLocation = repositoryBackupDeviceLocation;
_repositoryBackupHistory = repositoryBackupHistory;
_repositoryDatabaseSizes = repositoryDatabaseSizes;
_repositoryDiskSystem = repositoryDiskSystem;
_repositoryFailedDatabaseJobs = repositoryFailedDatabaseJobs;
_repositoryDatabaseReplication = repositoryDatabaseReplication;
_repositoryDatabaseLongRunningJob = repositoryDatabaseLongRunningJob;
_repositoryDatabaseSystem = repositoryDatabaseSystem;
_repositoryDiskBackup = repositoryDiskBackup;
_repositorySqlServerAgentEventLog = repositorySqlServerAgentEventLog;
_repositorySqlEventLog = repositorySqlEventLog;
_repositoryDatabaseOwner = repositoryDatabaseOwner;
_repositoryRecoveryModel = repositoryRecoveryModel;
_repositoryBelongToSystem = repositoryBelongToSystem;
}
public void Notify()
{
foreach (var field in this.GetType().GetProperties())
{
field.Save();
}
}
}
}
使用Fle.SQLServer.Core.Model;
使用Fle.SQLServer.Core.Services;
命名空间Fle.SQLServer.XmlFiles.Notifier
{
公共类XmlSerialization:INotifier
{
私有只读存储备份设备位置;
私人只读电子存储备份历史记录;
私有只读IRepository存储数据库大小;
私有只读存储磁盘系统;
私有只读IRepository存储失败的数据库作业;
私有只读存储数据库复制;
私人只读IRepository存储数据库LongRunningJob;
专用只读电子存储数据库系统;
专用只读存储磁盘备份;
私有只读IRepository存储SQLServerAgentEventLog;
私有只读IRepository\u repositorySqlEventLog;
私有只读iRepositoryDatabaseOwner;
私有只读IRepository\u repositoryRecoveryModel;
属于系统的专用只读IRepository存储库;
公共XML序列化(IRepository Repository BackupDeviceLocation,
i存储备份历史,
i存储库数据库大小,
i存托凭证系统,
i存储存储失败的数据库作业,
i存储库数据库复制,
iRepositoryDatabaseLongRunningJob,
电子存储数据库系统,
i存储存储磁盘备份,
i存储库SQLServerAgentEventLog,
iRepositorySqlEventLog,
iRepositoryDatabaseOwner,
iRepositoryRecoveryModel,
i存储存储(属于系统)
{
_repositoryBackupDeviceLocation=repositoryBackupDeviceLocation;
_repositoryBackupHistory=repositoryBackupHistory;
_repositoryDatabaseSizes=repositoryDatabaseSizes;
_repositoryDiskSystem=repositoryDiskSystem;
_repositoryFailedDatabaseJobs=repositoryFailedDatabaseJobs;
_repositoryDatabaseReplication=repositoryDatabaseReplication;
_repositoryDatabaseLongRunningJob=repositoryDatabaseLongRunningJob;
_repositoryDatabaseSystem=repositoryDatabaseSystem;
_repositoryDiskBackup=repositoryDiskBackup;
_repositorySqlServerAgentEventLog=repositorySqlServerAgentEventLog;
_repositorySqlEventLog=repositorySqlEventLog;
_repositoryDatabaseOwner=repositoryDatabaseOwner;
_repositoryRecoveryModel=repositoryRecoveryModel;
_repositoryBelongToSystem=repositoryBelongToSystem;
}
公告
{
foreach(此.GetType().GetProperties()中的var字段)
{
field.Save();
}
}
}
}
如果您有一个带有Save
方法的非通用存储库,那么您不需要反射
假设您的i假设
看起来像这样
public interface IRepository<T>
{
...
T Get(int id);
void Save();
}
并使i假设
得以实现
public interface IRepository<T> : IRepository
{
T Get(int id);
...
}
不需要肮脏的反射
如果仍然希望保持XmlSerialization
类字段和构造函数不变,可以执行以下操作
public void Notify()
{
var repositories = new IRepository[]
{
_repositoryBackupDeviceLocation,
repositoryBackupHistory,
...
...,
_repositoryBelongToSystem
};
foreach (var repo in repositories)
{
repo.Save();
}
}
与其使用
反射
,不如引入一个新的非通用接口:
public interface IRepository
{
void Save();
}
public interface IRepository<T> : IRepository
{
// Other methods with T
}
反射很慢而且很脏。如果方法名称更改,则不会出现编译错误等。名称空间Fle.SQLServer.XmlFiles.Notifier
namespace Fle.SQLServer.XmlFiles.Notifier
{
public class XmlSerialization<T> : INotifier
{
readonly IRepository<T> field;
public XmlSerialization(IRepository<T> repository)
{
field = repository;
}
public void Notify()
{
field.Save();
}
}
}
public class Registry : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<XmlSerialization<BackupDeviceLocationData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<BackupHistoryData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<BelongToSystemData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseLongRunningJobData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseOwnerData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseReplicationData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseSizesData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseSystemData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DiskBackupData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<FailedDatabaseJobsData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<RecoveryModelData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<SqlServerAgentEventLogData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<SqlServerEventLogData>>().As<INotifier>();
}
}
{
公共类XmlSerialization:INotifier
{
只读易读字段;
公共XmlSerialization(IRepository存储库)
{
字段=存储库;
}
公告
{
field.Save();
}
}
}
公共类注册表:Autofac.Module
{
受保护的覆盖无效负载(ContainerBuilder builder)
{
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
}
}
正如你们中的一些人所说,我重新思考了这个问题,并将XmlSerialization作为调用IRepository.Save的通用类,然后在程序集中的注册表中将XmlSerialization注册到INotifier接口。取而代之的是一系列对象,而不是一个保存对象。但是程序的一般逻辑会处理INotifier列表,并调用INotifier.Notify()如何定义IRepository
?可能重复
public interface IRepository
{
void Save();
}
public interface IRepository<T> : IRepository
{
// Other methods with T
}
public class XmlSerialization : INotifier
{
private readonly IRepository[] _repositories;
public XmlSerialization(params IRepository[] repositories)
{
this._repositories = repositories;
}
public void Notify()
{
foreach (IRepository repository in this._repositories)
{
repository.Save();
}
}
}
namespace Fle.SQLServer.XmlFiles.Notifier
{
public class XmlSerialization<T> : INotifier
{
readonly IRepository<T> field;
public XmlSerialization(IRepository<T> repository)
{
field = repository;
}
public void Notify()
{
field.Save();
}
}
}
public class Registry : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<XmlSerialization<BackupDeviceLocationData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<BackupHistoryData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<BelongToSystemData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseLongRunningJobData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseOwnerData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseReplicationData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseSizesData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DatabaseSystemData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<DiskBackupData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<FailedDatabaseJobsData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<RecoveryModelData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<SqlServerAgentEventLogData>>().As<INotifier>();
builder.RegisterType<XmlSerialization<SqlServerEventLogData>>().As<INotifier>();
}
}