-1

私は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"; }
    }
}

インターフェイスやビューモデルなど、私のコードをもう見る必要がある場合は、お知らせください。どんな助けでも大歓迎です!

4

3 に答える 3

2

あなたの例に関する限り、とIEnumerable<T>ほぼ同義であると考えることができますList<T>。それはオブジェクトのコレクションです。たった一つかもしれないし、何もないかもしれないし、百かもしれない。それ以上のことはありIEnumerableますが、あなたの目的のために考える必要があるのはそれだけです。

このコードでは:

[ImportMany]
public IEnumerable<IEmailAddressesProvider> AddressProviders { get; set; }

のエクスポートされたすべての実装を収集するように MEF に依頼していますIEmailAddressesProvider。返されるのはオブジェクトのコレクションです。たとえ 1 つしか見つからなかったとしても、要素が 1 つしかないコレクションが得られます。この後の行で:

ev.ViewModel.ProviderName = AddressProviders;

左側は を期待していると思いますstringが、右側は のコレクションですIEmailAddressesProviderProviderNameおそらく実際にはオブジェクト全体ではなく、のプロパティが必要であるという事実とは別にIEmailAddressesProvider、コレクション内のどのオブジェクトを使用するかを指定する必要もあります。これに対処するには、次の 2 つの方法があります。

  1. の実装が 1 つしかないことがわかっている場合はIEmailAddressesProvider、そのように変更ImportManyします。Import

    [Import]
    public IEmailAddressesProvider AddressProviders { get; set; }
    

    他の割り当てを に変更しev.ViewModel.ProviderName = AddressProviders.ProviderNameます。これは、 の 2 番目の実装をエクスポートするとすぐに壊れてしまうことに注意してくださいIEmailAddressesProvider。したがって、1 つしか存在しないことが本当にわかっている場合にのみ、これを行ってください。

  2. の実装が複数ある可能性がある場合はIEmailAddressesProvider、必要な特定のものを見つける必要があります。(他の回答が言ったAddressProvidersように)コレクションをクエリして、適切なオブジェクトを見つけ、その結果からプロパティを使用します。提供されたコードから必要なクエリについてこれ以上言うことはできません。FirstOrDefaultProviderName
于 2013-02-05T23:42:09.433 に答える
1

インターフェイスのプロパティと variable によって決定されるIEmailAddressesProviderから1 つが必要だと思います。AddressProvidersProviderNameprovider

それが true の場合は、最初に一致する AddressProvider を返すものを使用できEnumerable.FirstOrDefaultます。nullProviderName

// ...
ev.ViewModel.ProviderName = AddressProviders
    .FirstOrDefault(ap => ap.ProviderName == yourProviderName);
ev.ViewModel.Provider = provider;
// ...
于 2013-02-05T21:26:28.327 に答える
0

上記の回答に問題がある場合は、これらのいずれかを使用してみてください。

ev.ViewModel.ProviderName = AddressProviders.Where(p=> p.ProviderName == provider).Single();
ev.ViewModel.ProviderName = AddressProviders.Where(p=> p.ProviderName == provider).First();
于 2013-02-05T21:38:34.493 に答える