C# 在类中使用反射循环字段并在接口上调用函数

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)”的类型参数。

我试图使用反射在类XmlSerialization中循环我的IRepository字段。我无法在foreach循环中定义IRepository,而是尝试使用var。但是我无法调用IRepository.Save,不知何故,我需要在foreach循环中过滤通用IRepository

无法从用法推断方法“Fle.SQLServer.XmlFiles.Notifier.xmlsialization.Save(Fle.SQLServer.Core.Services.IRepository)”的类型参数。尝试显式指定类型参数

我理解我的问题,但不能解决它

我想在XmlSerialization上循环我的IRepository字段并调用save,而不调用类中的每个字段

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>();
    }
}