YoyoS
YoyoS

Reputation: 659

Playing MediaPlayer from standard lib

From my .NETStandard 2.1 lib, I don't have access to MediaPlayer class. A service from this same lib should play a mp3 file when an event occurs in one of its methods

My main project is a .NET5 WPF and this little code is working great when testing it inside separately:

private void PlayAlert()
{
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.Open(new Uri("alert.mp3", UriKind.Relative));
    mediaPlayer.Play();
} 

How would you cleanly an nicely connect my lib with this private method that only works here ?

Thanks !

Upvotes: 1

Views: 301

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125197

You can create an ISoundPlayer interface in your class library and everywhere you need that, pass it as a dependency to the constructor of the class.

Then in your Wpf application, implement that interface in a MySoundPlayer class and whenever you want to instantiate one of those classes of the class library which has a dependency to ISoundPlayer, pass MySoundPlayer to them.

There are some other possible solutions as well and if you are interested to learn about them read the note at the bottom of the answer about Inversion of Control.

Example

The following example doesn't use any DI framework, but creates a class library which has a MyClass which has a dependency to an interface called ISoundPlayer. Then in another project, a Wpf Application, implements the ISoundPlayer, instantiate MyClass and pass the implementation of ISoundPlayer to it. You can use the same using a DI library (which is out of scope of this q/a).

Follow these steps:

  1. Create a WPF Application, MyWpfApp

  2. Create a .NET standard class Library project, MyClassLibrary

  3. Add an ISoundPlayer interface to your class library:

    namespace MyClassLibrary
    {
        public interface ISoundPlayer
        {
            void PlaySound();
        }
    }
    
  4. Add a class that get ISoundPlayer interface in constructor:

    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();
            }
        }
    }
    
  5. Add reference of MyClassLibrary to your MyWpfApp.

  6. Create a MySoundPlayer class implementing the ISoundPlayerInterface:

    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();
            }
        }
    }
    
  7. Drop a button on main window and handle its click event, instantiate MyClass and pass an instance of MySoundPlayer to it.

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

Note

To achieve Inversion of Control you can consider the following options:

  • Dependency Injection: You can rely on an ISoundPlayer interface having a PlaySound method and inject this dependency into your library.
  • Event: You can raise an event in your library and let the consumers subscribe to the event and play sound.
  • Delegate: You may want to inject a delegate (as a property or through constructor) and use that delegate in your library.

Upvotes: 1

Related Questions