Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从标准库播放MediaPlayer_C#_Wpf_Class Library_.net 5 - Fatal编程技术网

C# 从标准库播放MediaPlayer

C# 从标准库播放MediaPlayer,c#,wpf,class-library,.net-5,C#,Wpf,Class Library,.net 5,从.netstandard2.1库中,我没有访问MediaPlayer类的权限。 当某个方法中发生事件时,来自该库的服务应播放mp3文件 我的主要项目是一个.NET5 WPF,当在内部单独测试它时,这个小代码工作得非常好: private void PlayAlert() { MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.Open(new Uri("alert.mp3", UriKind.Re

从.netstandard2.1库中,我没有访问MediaPlayer类的权限。 当某个方法中发生事件时,来自该库的服务应播放mp3文件

我的主要项目是一个.NET5 WPF,当在内部单独测试它时,这个小代码工作得非常好:

private void PlayAlert()
{
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.Open(new Uri("alert.mp3", UriKind.Relative));
    mediaPlayer.Play();
} 
如何将我的lib与这个只在这里工作的私有方法很好地连接起来


谢谢

您可以在类库中创建一个
ISoundPlayer
接口,在需要的任何地方,将其作为依赖项传递给类的构造函数

然后在您的Wpf应用程序中,在MySoundPlayer类中实现该接口,并且每当您想要实例化类库中依赖于ISoundPlayer的类之一时,将MySoundPlayer传递给它们

还有一些其他可能的解决方案,如果你有兴趣了解它们,请阅读答案底部关于控制反转的注释

示例

下面的示例不使用任何DI框架,而是创建了一个类库,其中包含一个MyClass,该MyClass依赖于一个名为ISoundPlayer的接口。然后在另一个项目中,一个Wpf应用程序实现ISoundPlayer,实例化MyClass并将ISoundPlayer的实现传递给它。您可以使用DI库(不在本q/a的范围内)使用相同的功能

遵循以下步骤:

  • 创建一个WPF应用程序MyWpfApp

  • 创建.NET标准类库项目MyClassLibrary

  • ISoundPlayer
    接口添加到类库:

    namespace MyClassLibrary
    {
        public interface ISoundPlayer
        {
            void PlaySound();
        }
    }
    
  • 添加在构造函数中获取ISoundPlayer接口的类:

    using System;
    
    namespace MyClassLibrary
    {
        public class MyCLass
        {
            ISoundPlayer soundPlayer;
            public MyCLass(ISoundPlayer soundPlayer)
            {
                this.soundPlayer = soundPlayer ??
                    throw new ArgumentNullException(nameof(soundPlayer));
            }
            public void DoSomething()
            {
                //Do something
                soundPlayer.PlaySound();
            }
        }
    }
    
  • 将MyClassLibrary的引用添加到MyWpfApp

  • 创建实现ISoundPlayerInterface的MySoundPlayer类:

    using MyClassLibrary;
    using System;
    using System.Windows.Media;
    
    namespace MyWpfApp
    {
        public class MySoundPlayer : ISoundPlayer
        {
            public void PlaySound()
            {
                //var player = new MediaPlayer();
                //player.Open(new Uri("alert.mp3"));
                //player.Play();
                //or simply
                System.Media.SystemSounds.Beep.Play();
            }
        }
    }
    
  • 在主窗口上放置一个按钮并处理其单击事件,实例化MyClass并将MySoundPlayer的实例传递给它

    private void button_Click(object sender, RoutedEventArgs e)
    {
        var myClass = new MyClassLibrary.MyCLass(new MySoundPlayer());
        myClass.DoSomething();
    }
    
  • 注意

    <>你可以考虑以下选项:

    • 依赖项注入:您可以依赖具有PlaySoundPlayer方法的ISoundPlayer接口,并将此依赖项注入库中
    • 事件:您可以在库中发起事件,让消费者订阅事件并播放声音
    • 委托:您可能希望插入委托(作为属性或通过构造函数),并在库中使用该委托

    您能举一个例子吗?我已经在使用ioc了,但是我所有的界面和代码都在库中,所以MediaPlayer不能在那里。我编辑了答案并删除了其余的示例,它超出了答案的范围,对未来的读者来说太长了。如果您仍然对上一版本感兴趣,你可以。谢谢你的例子,但我不想从WPF方面引发事件。假设只有来自我的标准库的后台服务会在需要时执行声音。所以没有按钮点击,WPF没有事件。我想我必须从后台服务发送一个事件,并将一些WPF处理程序加载到服务中,但这就是我不知道如何干净地完成的。可能是可以观察到的模式?没什么区别。只需传入依赖项并在后台服务中使用它。后台服务只不过是一个类,它具有类似于
    DoSomething
    的方法,这些方法在某个时间点运行。