我没有使用过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"; }
}
}
如果您需要查看我的代码,例如接口或viewmodel,请告诉我。任何帮助将不胜感激!
答案 0 :(得分:2)
就您的示例而言,您可以认为IEnumerable<T>
几乎与List<T>
同义:它是对象的集合;它可能只是一个,也可能是一个,它可能是一百个。 IEnumerable
比{I}更多,但出于您的目的,您需要考虑的事情。
在此代码中:
[ImportMany]
public IEnumerable<IEmailAddressesProvider> AddressProviders { get; set; }
您要求MEF收集IEmailAddressesProvider
的所有导出实现。你得到的是一组对象:即使它只找到一个,你仍然得到一个只有一个元素的集合。在后面这一行:
ev.ViewModel.ProviderName = AddressProviders;
我猜左手边是期待string
,但右边是IEmailAddressesProvider
的集合。除了您可能实际需要ProviderName
的{{1}}属性而不是整个对象之外,您还需要说明要使用的集合中的哪个对象。有两种方法可以解决这个问题:
如果您知道只有一个IEmailAddressesProvider
的实施,那么将IEmailAddressesProvider
更改为ImportMany
就像这样
Import
并将其他作业更改为[Import]
public IEmailAddressesProvider AddressProviders { get; set; }
。请注意,一旦导出ev.ViewModel.ProviderName = AddressProviders.ProviderName
的第二个实现,这将会中断,所以只有在您确实知道只有一个实现时才会这样做。
IEmailAddressesProvider
的多个实现,那么您需要找到所需的特定实现。您可以使用IEmailAddressesProvider
(如其他答案所述)查询AddressProviders
集合,以查找正确的对象,然后使用该结果中的FirstOrDefault
属性。从您提供的代码中无法详细说明您需要的查询。答案 1 :(得分:1)
我只是在猜测,您需要IEmailAddressesProvider
中的AddressProviders
个ProviderName
,该provider
由界面中的null
属性和变量ProviderName
确定。
如果确实如此,您可以使用Enumerable.FirstOrDefault
返回第一个匹配的AddressProvider,如果找不到给定的// ...
ev.ViewModel.ProviderName = AddressProviders
.FirstOrDefault(ap => ap.ProviderName == yourProviderName);
ev.ViewModel.Provider = provider;
// ...
,则返回{{1}}:
{{1}}
答案 2 :(得分:0)
如果您对上述答案有疑问,请尝试使用其中一种。
ev.ViewModel.ProviderName = AddressProviders.Where(p=> p.ProviderName == provider).Single();
ev.ViewModel.ProviderName = AddressProviders.Where(p=> p.ProviderName == provider).First();