使用IEnumerable<>;以及创建具有其类型的属性
本文关键字:属性 创建 类型 lt IEnumerable gt 使用 | 更新日期: 2023-09-27 17:57:43
我很少使用Linq,也没有使用IEnumberable类。以下是我的代码和对我遇到的问题的解释。
public class EmailService : IEmailService
{
#region Constructors
#endregion
#region Properties
[ImportMany]
public IEnumerable<IEmailAddressesProvider> AddressProviders { get; set; }
#endregion
这些是我需要在EmailService类中使用的属性。这是电子邮件地址提供程序的集合。
我需要使用存储在中的内容,并将其基本上连接到ViewModel,就像我在本代码的下一节中使用这些其他属性一样。
IUserInteractionService uiService = AllianceApp.Container.GetExportedValue<IUserInteractionService>();
IEmailSetupProvider provider = new EmailSetupProvider();
EmailView ev = AllianceApp.Container.GetExportedValue<EmailView>();
ev.ViewModel.ProviderName = AddressProviders;
ev.ViewModel.Provider = provider;
ev.ViewModel.Bcc = bccAddress;
ev.ViewModel.Cc = ccAddress;
ev.ViewModel.ToAddress = toAddress;
ev.ViewModel.Body = body;
ev.ViewModel.Subject = subject;
ev.ViewModel.Attachments = attachments;
return uiService.ShowDialog(ev, RegionNames.MainRegion);
}
上面写着"地址提供商是我试图创建此属性的地方。
IEmailAddressesProvider接口:
public interface IEmailAddressesProvider
{
string ProviderName { get; }
IEnumerable<EmailAddress> GetEmailUsers();
}
GetEmailUsers方法(以防万一):
[Export(typeof(IEmailAddressesProvider))]
public class EmailAddressProvider : IEmailAddressesProvider
{
#region Private Properties
private static readonly IEncryptionService encryptionService = AllianceApp.Container.GetExportedValue<IEncryptionService>();
#endregion
public string ProviderName
{
get { return "Alliance Users"; }
}
public IEnumerable<EmailAddress> GetEmailUsers()
{
IUserRepository userRepo = AllianceApp.Container.GetExportedValue<IUserRepository>();
IEnumerable<User> users = userRepo.GetAllUsers().Where(a => a.IsDeleted == false).OrderBy(a => a.UserID).AsEnumerable();
List<EmailAddress> AddressList = new List<EmailAddress>();
foreach (var user in users)
{
if (user.DisplayName != null && user.EmailAddress != null && user.DisplayName != string.Empty && user.EmailAddress != string.Empty)
AddressList.Add(new EmailAddress() { DisplayName = encryptionService.DecryptString(user.DisplayName), Email = encryptionService.DecryptString(user.EmailAddress) });
}
AddressList.OrderBy(u => u.DisplayName);
return AddressList;
}
}
ProviderName专用代码(用于EmailAddressesProvider.cs):
[Export(typeof(IEmailAddressesProvider))]
public class EmailAddressProvider : IEmailAddressesProvider
{
#region Private Properties
private static readonly IEncryptionService encryptionService = AllianceApp.Container.GetExportedValue<IEncryptionService>();
#endregion
public string ProviderName
{
get { return "Alliance Users"; }
}
}
如果你需要查看我的代码,比如接口或视图模型,请告诉我。任何帮助都将不胜感激!
就您的示例而言,您可以将IEnumerable<T>
视为List<T>
的同义词:它是对象的集合;可能只有一个,也可能没有,也可能有一百个。IEnumerable
还有更多内容,但出于您的目的,这是您需要考虑的内容。
在此代码中:
[ImportMany]
public IEnumerable<IEmailAddressesProvider> AddressProviders { get; set; }
您要求MEF收集IEmailAddressesProvider
的所有导出实现。你得到的是一个对象集合:即使它只找到一个,你仍然得到一个只有一个元素的集合。在后面的行中:
ev.ViewModel.ProviderName = AddressProviders;
我猜左手边期望的是string
,但右手边是IEmailAddressesProvider
的集合。除了您可能实际想要IEmailAddressesProvider
的ProviderName
属性而不是整个对象之外,您还需要说明要使用集合中的哪个对象。有两种方法可以解决这个问题:
如果您知道
IEmailAddressesProvider
只有一个实现,那么像一样将ImportMany
更改为Import
[Import] public IEmailAddressesProvider AddressProviders { get; set; }
并且将该另一个指派改变为CCD_ 12。请注意,一旦导出
IEmailAddressesProvider
的第二个实现,这种情况就会中断,所以只有在您真的知道只能有一个实现的情况下才能这样做。- 如果
IEmailAddressesProvider
可能有几个实现,那么您需要找到您想要的特定实现。您可以使用类似FirstOrDefault
的内容查询AddressProviders
集合(正如其他答案所说),以找到正确的对象,然后使用该结果中的ProviderName
属性。从您提供的代码中不可能对您需要的查询有更多的了解
我只是猜测,您想要AddressProviders
中的单个IEmailAddressesProvider
,它由接口中的ProviderName
属性和变量provider
确定。
如果这是真的,您可以使用返回第一个匹配AddressProvider的Enumerable.FirstOrDefault
,或者如果没有找到具有给定ProviderName
:的null
// ...
ev.ViewModel.ProviderName = AddressProviders
.FirstOrDefault(ap => ap.ProviderName == yourProviderName);
ev.ViewModel.Provider = provider;
// ...
如果您对上面的答案有问题,请尝试使用其中一个。
ev.ViewModel.ProviderName = AddressProviders.Where(p=> p.ProviderName == provider).Single();
ev.ViewModel.ProviderName = AddressProviders.Where(p=> p.ProviderName == provider).First();