How do we generate the ITokenBuilder class/interface in C# that has all the necessary tags and stuff like in the code snippet below:
/// <summary>
/// Initializes a new instance of the <see cref="Token"/> class.
/// </summary>
/// <param name="builder">Token builder</param>
protected Token(ITokenBuilder builder)
{
Lexeme = builder.Lexeme;
LeftTrivia = builder.LeftTrivia;
RightTrivia = builder.RightTrivia;
}
Do I need to manually type in the /// <summary> stuff?
Related
Problem
My application use accelerometer data via Microsoft.Devices.Sensors.Accelerometer class
Now I wanna write Unit or CodedUI tests, for this reason I need to have a special test implementation of Accelerometer to controlling returned data
In theory I have 3 options:
Create subclass of Accelerometer - impossible because Accelerometer is sealed class
By using reflection replace implementation of Accelerometer at run-time - isn't best option IMHO
Create subclass of SensorBase<AccelerometerReading> - good option
I have decided to go by #1 and implement my TestAccelerometer as child of SensorBase<AccelerometerReading>
And here is I have problem:
`Error CS1729 'SensorBase<AccelerometerReading>' does not contain a constructor that takes 0 arguments`
Error pretty clear I have looked in decompiled code (JetBrains dotPeak tool) and don't found any constructors at all.
Questions
How can I found proper constructor to use in my TestAccelerometer implementation?
Decompiled code
Microsoft.Devices.Sensors.Accelerometer
// Type: Microsoft.Devices.Sensors.Accelerometer
// Assembly: Microsoft.Devices.Sensors, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e
// MVID: 81ED89AA-6B11-4B39-BAFA-38D59CBB1E3B
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.0\Microsoft.Devices.Sensors.dll
using System;
namespace Microsoft.Devices.Sensors
{
/// <summary>
/// Provides Windows Phone applications access to the device’s accelerometer sensor.
/// </summary>
public sealed class Accelerometer : SensorBase<AccelerometerReading>
{
/// <summary>
/// Gets or sets whether the device on which the application is running supports the accelerometer sensor.
/// </summary>
///
/// <returns>
/// true if the device on which the application is running supports the accelerometer sensor; otherwise, false.
/// </returns>
public static bool IsSupported { get; internal set; }
/// <summary>
/// Gets the current state of the accelerometer. The value is a member of the <see cref="T:Microsoft.Devices.Sensors.SensorState"/> enumeration.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:Microsoft.Devices.Sensors.SensorState"/>.
/// </returns>
public SensorState State { get; private set; }
/// <summary>
/// Occurs when new data arrives from the accelerometer. This method is deprecated in the current release. Applications should use the <see cref="E:Microsoft.Devices.Sensors.SensorBase`1.CurrentValueChanged"/> event of the <see cref="T:Microsoft.Devices.Sensors.SensorBase`1"/> class instead.
/// </summary>
[Obsolete("use CurrentValueChanged")]
public event EventHandler<AccelerometerReadingEventArgs> ReadingChanged;
static Accelerometer();
/// <summary>
/// Releases the managed and unmanaged resources used by the <see cref="T:Microsoft.Devices.Sensors.Accelerometer"/>.
/// </summary>
public new void Dispose();
/// <summary>
/// Starts data acquisition from the accelerometer.
/// </summary>
public new void Start();
/// <summary>
/// Stops data acquisition from the accelerometer.
/// </summary>
public new void Stop();
}
}
Microsoft.Devices.Sensors.SensorBase
// Type: Microsoft.Devices.Sensors.SensorBase`1
// Assembly: Microsoft.Devices.Sensors, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e
// MVID: 81ED89AA-6B11-4B39-BAFA-38D59CBB1E3B
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.0\Microsoft.Devices.Sensors.dll
using System;
using System.Security;
namespace Microsoft.Devices.Sensors
{
/// <summary>
/// The base class for all Windows Phone sensor classes.
/// </summary>
/// <typeparam name="TSensorReading">The type of reading returned by the sensor.</typeparam>
public abstract class SensorBase<TSensorReading> : IDisposable where TSensorReading : ISensorReading
{
/// <summary>
/// Gets an object that implements <see cref="T:Microsoft.Devices.Sensors.ISensorReading"/> that contains the current value of the sensor. This object will be one of the following types, depending on which sensor is being referenced: <see cref="T:Microsoft.Devices.Sensors.AccelerometerReading"/>, <see cref="T:Microsoft.Devices.Sensors.CompassReading"/>, <see cref="T:Microsoft.Devices.Sensors.GyroscopeReading"/>, <see cref="T:Microsoft.Devices.Sensors.MotionReading"/>.
/// </summary>
///
/// <returns>
/// An object that implements <see cref="T:Microsoft.Devices.Sensors.ISensorReading"/> that contains the current value of the sensor.
/// </returns>
public TSensorReading CurrentValue { get; }
/// <summary>
/// Gets or sets the preferred time between <see cref="E:Microsoft.Devices.Sensors.SensorBase`1.CurrentValueChanged"/> events.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:System.TimeSpan"/>. The preferred time between CurrentValueChanged events.
/// </returns>
public TimeSpan TimeBetweenUpdates { get; set; }
/// <summary>
/// Gets the validity of the sensor’s data.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:System.Boolean"/>. true if the sensor’s data is valid; otherwise, false.
/// </returns>
public bool IsDataValid { get; }
/// <summary>
/// Occurs when new data arrives from the sensor.
/// </summary>
public event EventHandler<SensorReadingEventArgs<TSensorReading>> CurrentValueChanged;
static SensorBase();
internal SensorBase();
/// <summary>
/// Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection.
/// </summary>
[SecuritySafeCritical]
~SensorBase();
/// <summary>
/// Releases the managed and unmanaged resources used by the sensor.
/// </summary>
[SecuritySafeCritical]
public void Dispose();
/// <summary>
/// Starts acquisition of data from the sensor.
/// </summary>
public virtual void Start();
/// <summary>
/// Stops acquisition of data from the sensor.
/// </summary>
public virtual void Stop();
}
}
You did find a constructor:
internal SensorBase();
This constructor prevents the SensorBase from having a default public constructor and this class cannot be subclassed from outside its assembly.
Testing it will be complicated. You could redesign the app and use a wrapper/adapter for the Accelerometer just for the puropse of testing or you could check if there's a possibility of mocking a sealed class on Windows Phone.
Question
I want to create a unit test for Credentials class that verifies the password for a given credentials after executing Calculate() method it its equal to the password calculated by an object that implements IPasswordCalculator interface.
Actually, the mock object that I created returns string.Empty value when calls Calculate(ICredentials) method, instead of Pa$$w0rd, that would be the desired return.
Then...
How I can implement this test without having to manually create a stub class?
How I can define the callback method on mock object to always return Pa$$w0rd?
Thanks in advance.
Code
IPasswordCalculator interface
/// <summary>
/// The password calculator interface.
/// </summary>
public interface IPasswordCalculator
{
/// <summary>
/// Calculates the user password using
/// <paramref name="credentials"/> instance.
/// </summary>
/// <param name="credentials">
/// <see cref="ICredentials"/> to perform the calculation.
/// </param>
void Calculate(ICredentials credentials);
}
ICredentials interface
/// <summary>
/// The Credentials interface.
/// </summary>
public interface ICredentials
{
/// <summary>
/// Gets or sets the user password.
/// </summary>
string Password { get; set; }
/// <summary>
/// Gets the user name.
/// </summary>
string Username { get; }
/// <summary>
/// Calculates the password.
/// </summary>
void Calculate();
}
Credentials implementation
/// <summary>
/// User credentials.
/// </summary>
public sealed class Credentials : ICredentials
{
/// <summary>
/// Initializes a new instance of the <see cref="Credentials" /> class.
/// </summary>
/// <param name="passwordCalculator">
/// The credentials calculator.
/// </param>
/// <param name="username">
/// The user name.
/// </param>
public Credentials(IPasswordCalculator passwordCalculator, string username)
{
this.Calculator = passwordCalculator;
this.Username = username;
this.Password = string.Empty;
}
/// <summary>
/// Calculates the password.
/// </summary>
public void Calculate()
{
if (null != this.Calculator)
{
this.Calculator.Calculate(this);
}
}
}
Test
/// <summary>
/// Calculate should set password value expected using calculator.
/// </summary>
[TestMethod]
public void CalculateShouldSetPasswordValueExpectedUsingCalculator()
{
ICredentials credentials = null;
var repo = new MockRepository(MockBehavior.Default);
var mock = repo.Create<IPasswordCalculator>();
mock.Setup(x => x.Calculate(credentials))
.Callback(() => { credentials.Password = "Pa$$w0rd"; });
IPasswordCalculator calculator = mock.Object;
credentials = new Credentials(calculator, "Me");
credentials.Calculate();
Assert.AreEqual("Pa$$w0rd", credentials.Password); // Fail
}
You need to setup your mock in the following way
mock.Setup(x => x.Calculate(It.IsAny<ICredentials>()))
.Callback((ICredentials c) => { c.Password = "Pa$$w0rd"; });
Thus you tell it "whatever ICredentials you get as the parameter of the Calculate method, set its Password to 'Pa$$word'"
I think you need to initialize the credentials variable before the call to mock.Setup(). With your code, Moq expects a call credentials.Calculate(null).
Using C# i'm trying to retrieve the name of the song that is currently playing and display it on a listBox, so every song that plays, it's shown in the listbox.
Using System;
Using WMPLib;
public IWMPMedia currentMedia { get; set; }
private void button1_Click(object sender, EventArgs e)
{
Player = new WMPLib.WindowsMediaPlayer();
string song = Player.currentMedia.name.ToString();
listBox1.Items.Add(song);
}
But it throws me the exception.
"Object reference not set to an instance of an object" here:
string song = Player.currentMedia.name.ToString();
Does anyone knows how to solve this?
You will have to use COM/OLE to do this. I did a program that did exactly that a little while ago, unfortunately tho I cannot find my client code, but I still have the code that implements IOleClientSite/IOleServiceProvider for WMPLib.
I found that code at the following URL:
http://sirayuki.sakura.ne.jp/WmpSample/WmpRemote.zip
Its some code that was writen by Jonathan Dibble, a Microsoft employee if I remember correctly. There is a CHM in the Zip with some explanation on each of the classes.
Heres the code that I still have, in case the link goes down, but like I said I cannot find my code that uses it. It worked almost correctly but I remember that one of the bug left was that it would leave behind wmplayer.exe processes after the media player and my application were closed.
UPDATE!
found some client code and a slighlty modified version of RemotedWindowsMediaPlayer.cs
I just found some coded that I tested this with, and it works. Its from a Winform project, and you need to reference WMPLib for this to work.
In my form I added a button and this code:
/// <summary>
/// Default Constructor
/// </summary>
RemotedWindowsMediaPlayer rm;
public FrmMain()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//Call me old fashioned - I like to do this stuff manually. You can do a drag
//drop if you like, it won't change the results.
rm = new RemotedWindowsMediaPlayer();
rm.Dock = System.Windows.Forms.DockStyle.Top;
panel1.Controls.Add(rm);
return;
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(((WMPLib.IWMPPlayer4)rm.GetOcx()).currentMedia.sourceURL);
}
RemotedWindowsMediaPLayer.cs:
namespace RemoteWMP
{
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using WMPLib;
/// <summary>
/// This is the actual Windows Media Control.
/// </summary>
[System.Windows.Forms.AxHost.ClsidAttribute("{6bf52a52-394a-11d3-b153-00c04f79faa6}")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class RemotedWindowsMediaPlayer : System.Windows.Forms.AxHost,
IOleServiceProvider,
IOleClientSite
{
/// <summary>
/// Used to attach the appropriate interface to Windows Media Player.
/// In here, we call SetClientSite on the WMP Control, passing it
/// the dotNet container (this instance.)
/// </summary>
protected override void AttachInterfaces()
{
try
{
//Get the IOleObject for Windows Media Player.
IOleObject oleObject = this.GetOcx() as IOleObject;
if (oleObject != null)
{
//Set the Client Site for the WMP control.
oleObject.SetClientSite(this as IOleClientSite);
// Try and get the OCX as a WMP player
if (this.GetOcx() as IWMPPlayer4 == null)
{
throw new Exception(string.Format("OCX is not an IWMPPlayer4! GetType returns '{0}'",
this.GetOcx().GetType()));
}
}
else
{
throw new Exception("Failed to get WMP OCX as an IOleObject?!");
}
return;
}
catch (System.Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
#region IOleServiceProvider Memebers - Working
/// <summary>
/// During SetClientSite, WMP calls this function to get the pointer to <see cref="RemoteHostInfo"/>.
/// </summary>
/// <param name="guidService">See MSDN for more information - we do not use this parameter.</param>
/// <param name="riid">The Guid of the desired service to be returned. For this application it will always match
/// the Guid of <see cref="IWMPRemoteMediaServices"/>.</param>
/// <returns></returns>
IntPtr IOleServiceProvider.QueryService(ref Guid guidService, ref Guid riid)
{
//If we get to here, it means Media Player is requesting our IWMPRemoteMediaServices interface
if (riid == new Guid("cbb92747-741f-44fe-ab5b-f1a48f3b2a59"))
{
IWMPRemoteMediaServices iwmp = new RemoteHostInfo();
return Marshal.GetComInterfaceForObject(iwmp, typeof(IWMPRemoteMediaServices));
}
throw new System.Runtime.InteropServices.COMException("No Interface", (int) HResults.E_NOINTERFACE);
}
#endregion
#region IOleClientSite Members
/// <summary>
/// Not in use. See MSDN for details.
/// </summary>
/// <exception cref="System.Runtime.InteropServices.COMException">E_NOTIMPL</exception>
void IOleClientSite.SaveObject()
{
throw new System.Runtime.InteropServices.COMException("Not Implemented", (int) HResults.E_NOTIMPL);
}
/// <summary>
/// Not in use. See MSDN for details.
/// </summary>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
object IOleClientSite.GetMoniker(uint dwAssign, uint dwWhichMoniker)
{
throw new System.Runtime.InteropServices.COMException("Not Implemented", (int) HResults.E_NOTIMPL);
}
/// <summary>
/// Not in use. See MSDN for details.
/// </summary>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
object IOleClientSite.GetContainer()
{
return (int)HResults.E_NOINTERFACE;
}
/// <summary>
/// Not in use. See MSDN for details.
/// </summary>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
void IOleClientSite.ShowObject()
{
throw new System.Runtime.InteropServices.COMException("Not Implemented", (int) HResults.E_NOTIMPL);
}
/// <summary>
/// Not in use. See MSDN for details.
/// </summary>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
void IOleClientSite.OnShowWindow(bool fShow)
{
throw new System.Runtime.InteropServices.COMException("Not Implemented", (int) HResults.E_NOTIMPL);
}
/// <summary>
/// Not in use. See MSDN for details.
/// </summary>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
void IOleClientSite.RequestNewObjectLayout()
{
throw new System.Runtime.InteropServices.COMException("Not Implemented", (int) HResults.E_NOTIMPL);
}
#endregion
/// <summary>
/// Default Constructor.
/// </summary>
public RemotedWindowsMediaPlayer() :
base("6bf52a52-394a-11d3-b153-00c04f79faa6")
{
}
}
}
RemoteHostInfo.cs
using System;
namespace RemoteWMP
{
using System.Runtime.InteropServices;
/// <summary>
/// This class contains the information to return to Media Player about our remote service.
/// </summary>
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class RemoteHostInfo :
IWMPRemoteMediaServices
{
#region IWMPRemoteMediaServices Members
/// <summary>
/// Returns "Remote" to tell media player that we want to remote the WMP application.
/// </summary>
/// <returns></returns>
public string GetServiceType()
{
return "Remote";
}
/// <summary>
/// The Application Name to show in Windows Media Player switch to menu
/// </summary>
/// <returns></returns>
public string GetApplicationName()
{
return System.Diagnostics.Process.GetCurrentProcess().ProcessName;
}
/// <summary>
/// Not in use, see MSDN for more info.
/// </summary>
/// <param name="name"></param>
/// <param name="dispatch"></param>
/// <returns></returns>
public HResults GetScriptableObject(out string name, out object dispatch)
{
name = null;
dispatch = null;
//return (int) HResults.S_OK;//NotImplemented
return HResults.E_NOTIMPL;
}
/// <summary>
/// For skins, not in use, see MSDN for more info.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public HResults GetCustomUIMode(out string file)
{
file = null;
return HResults.E_NOTIMPL;//NotImplemented
}
#endregion
}
}
COM Interfaces.cs
using System;
namespace RemoteWMP
{
using System.Runtime.InteropServices;
#region Useful COM Enums
/// <summary>
/// Represents a collection of frequently used HRESULT values.
/// You may add more HRESULT VALUES, I've only included the ones used
/// in this project.
/// </summary>
public enum HResults
{
/// <summary>
/// HRESULT S_OK
/// </summary>
S_OK = unchecked((int)0x00000000),
/// <summary>
/// HRESULT S_FALSE
/// </summary>
S_FALSE = unchecked((int)0x00000001),
/// <summary>
/// HRESULT E_NOINTERFACE
/// </summary>
E_NOINTERFACE = unchecked((int)0x80004002),
/// <summary>
/// HRESULT E_NOTIMPL
/// </summary>
E_NOTIMPL = unchecked((int)0x80004001),
/// <summary>
/// USED CLICKED CANCEL AT SAVE PROMPT
/// </summary>
OLE_E_PROMPTSAVECANCELLED = unchecked((int)0x8004000C),
}
/// <summary>
/// Enumeration for <see cref="IOleObject.GetMiscStatus"/>
/// </summary>
public enum DVASPECT
{
/// <summary>
/// See MSDN for more information.
/// </summary>
Content = 1,
/// <summary>
/// See MSDN for more information.
/// </summary>
Thumbnail = 2,
/// <summary>
/// See MSDN for more information.
/// </summary>
Icon = 3,
/// <summary>
/// See MSDN for more information.
/// </summary>
DocPrint = 4
}
/// <summary>
/// Emumeration for <see cref="IOleObject.Close"/>
/// </summary>
public enum TAGOLECLOSE :uint{
OLECLOSE_SAVEIFDIRTY = unchecked((int)0),
OLECLOSE_NOSAVE = unchecked((int)1),
OLECLOSE_PROMPTSAVE = unchecked((int)2)
}
#endregion
#region IWMPRemoteMediaServices
/// <summary>
/// Interface used by Media Player to determine WMP Remoting status.
/// </summary>
[ComImport,
ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("CBB92747-741F-44fe-AB5B-F1A48F3B2A59")]
public interface IWMPRemoteMediaServices
{
/// <summary>
/// Service type.
/// </summary>
/// <returns><code>Remote</code> if the control is to be remoted (attached to WMP.)
/// <code>Local</code>if this is an independent WMP instance not connected to WMP application. If you want local, you shouldn't bother
/// using this control!
/// </returns>
[return: MarshalAs(UnmanagedType.BStr)]
string GetServiceType();
/// <summary>
/// Value to display in Windows Media Player Switch To Application menu option (under View.)
/// </summary>
/// <returns></returns>
[return: MarshalAs(UnmanagedType.BStr)]
string GetApplicationName();
/// <summary>
/// Not in use, see MSDN for details.
/// </summary>
/// <param name="name"></param>
/// <param name="dispatch"></param>
/// <returns></returns>
[PreserveSig]
[return: MarshalAs(UnmanagedType.U4)]
HResults GetScriptableObject([MarshalAs(UnmanagedType.BStr)] out string name,
[MarshalAs(UnmanagedType.IDispatch)] out object dispatch);
/// <summary>
/// Not in use, see MSDN for details.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[PreserveSig]
[return: MarshalAs(UnmanagedType.U4)]
HResults GetCustomUIMode([MarshalAs(UnmanagedType.BStr)] out string file);
}
#endregion
#region IOleServiceProvider
/// <summary>
/// Interface used by Windows Media Player to return an instance of IWMPRemoteMediaServices.
/// </summary>
[ComImport,
GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(true)]
public interface IOleServiceProvider
{
/// <summary>
/// Similar to QueryInterface, riid will contain the Guid of an object to return.
/// In our project we will look for <see cref="IWMPRemoteMediaServices"/> Guid and return the object
/// that implements that interface.
/// </summary>
/// <param name="guidService"></param>
/// <param name="riid">The Guid of the desired Service to provide.</param>
/// <returns>A pointer to the interface requested by the Guid.</returns>
IntPtr QueryService(ref Guid guidService, ref Guid riid);
}
/// <summary>
/// This is an example of an INCORRECT entry - do not use, unless you want your app to break.
/// </summary>
[ComImport,
GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(true)]
public interface BadIOleServiceProvider
{
/// <summary>
/// This is incorrect because it causes our return interface to be boxed
/// as an object and a COM callee may not get the correct pointer.
/// </summary>
/// <param name="guidService"></param>
/// <param name="riid"></param>
/// <returns></returns>
/// <example>
/// For an example of a correct definition, look at <see cref="IOleServiceProvider"/>.
/// </example>
[return: MarshalAs(UnmanagedType.Interface)]
object QueryService(ref Guid guidService, ref Guid riid);
}
#endregion
#region IOleClientSite
/// <summary>
/// Need to implement this interface so we can pass it to <see cref="IOleObject.SetClientSite"/>.
/// All functions return E_NOTIMPL. We don't need to actually implement anything to get
/// the remoting to work.
/// </summary>
[ComImport,
ComVisible(true),
Guid("00000118-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown) ]
public interface IOleClientSite
{
/// <summary>
/// See MSDN for more information. Throws <see cref="COMException"/> with id of E_NOTIMPL.
/// </summary>
/// <exception cref="COMException">E_NOTIMPL</exception>
void SaveObject();
/// <summary>
/// See MSDN for more information. Throws <see cref="COMException"/> with id of E_NOTIMPL.
/// </summary>
/// <exception cref="COMException">E_NOTIMPL</exception>
[return: MarshalAs(UnmanagedType.Interface)]
object GetMoniker(uint dwAssign, uint dwWhichMoniker);
/// <summary>
/// See MSDN for more information. Throws <see cref="COMException"/> with id of E_NOTIMPL.
/// </summary>
/// <exception cref="COMException">E_NOTIMPL</exception>
[return: MarshalAs(UnmanagedType.Interface)]
object GetContainer();
/// <summary>
/// See MSDN for more information. Throws <see cref="COMException"/> with id of E_NOTIMPL.
/// </summary>
/// <exception cref="COMException">E_NOTIMPL</exception>
void ShowObject();
/// <summary>
/// See MSDN for more information. Throws <see cref="COMException"/> with id of E_NOTIMPL.
/// </summary>
/// <exception cref="COMException">E_NOTIMPL</exception>
void OnShowWindow(bool fShow);
/// <summary>
/// See MSDN for more information. Throws <see cref="COMException"/> with id of E_NOTIMPL.
/// </summary>
/// <exception cref="COMException">E_NOTIMPL</exception>
void RequestNewObjectLayout();
}
#endregion
#region IOleObject
/// <summary>
/// This interface is implemented by WMP ActiveX/COM control.
/// The only function we need is <see cref="SetClientSite"/>.
/// </summary>
[ComImport, ComVisible(true),
Guid("00000112-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleObject
{
/// <summary>
/// Used to pass our custom <see cref="IOleClientSite"/> object to WMP. The object we pass must also
/// implement <see cref="IOleServiceProvider"/> to work right.
/// </summary>
/// <param name="pClientSite">The <see cref="IOleClientSite"/> to pass.</param>
void SetClientSite(IOleClientSite pClientSite);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[return: MarshalAs(UnmanagedType.Interface)]
IOleClientSite GetClientSite();
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void SetHostNames(
[MarshalAs(UnmanagedType.LPWStr)]string szContainerApp,
[MarshalAs(UnmanagedType.LPWStr)]string szContainerObj);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void Close(uint dwSaveOption);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void SetMoniker(uint dwWhichMoniker, object pmk);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[return: MarshalAs(UnmanagedType.Interface)]
object GetMoniker(uint dwAssign, uint dwWhichMoniker);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void InitFromData(object pDataObject, bool fCreation, uint dwReserved);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
object GetClipboardData(uint dwReserved);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void DoVerb(uint iVerb, uint lpmsg, [MarshalAs(UnmanagedType.Interface)]object pActiveSite,
uint lindex, uint hwndParent, uint lprcPosRect);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[return: MarshalAs(UnmanagedType.Interface)]
object EnumVerbs();
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void Update();
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[PreserveSig]
[return: MarshalAs(UnmanagedType.U4)]
HResults IsUpToDate();
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
Guid GetUserClassID();
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetUserType(uint dwFormOfType);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void SetExtent(uint dwDrawAspect, [MarshalAs(UnmanagedType.Interface)] object psizel);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[return: MarshalAs(UnmanagedType.Interface)]
object GetExtent(uint dwDrawAspect);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
uint Advise([MarshalAs(UnmanagedType.Interface)]object pAdvSink);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void Unadvise(uint dwConnection);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
[return: MarshalAs(UnmanagedType.Interface)]
object EnumAdvise();
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
uint GetMiscStatus([MarshalAs(UnmanagedType.U4)] DVASPECT dwAspect);
/// <summary>
/// Implemented by Windows Media Player ActiveX control.
/// See MSDN for more information.
/// </summary>
void SetColorScheme([MarshalAs(UnmanagedType.Interface)] object pLogpal);
}
#endregion
}
Not sure if I'm even calling this right but I wanted to start adding some documentation to my classes, methods, properties, etc. I know this is probably super obvious but I never really learned it. I'm not sure where to start.
Just to clarify whenever you roll over a class (or method, property, etc.) it shows a tooltip in Visual Studio with some documentation on that specific method.
class Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer
Provides background access to audio playback functionality such as play, pause, fast-forward, and rewind.
What is that called and how can I implement this in my C# application?
You can use /// or GhostDoc
Edit:
In first case you'll get
/// <summary>
///
/// </summary>
class A
{
/// <summary>
///
/// </summary>
public A() { }
/// <summary>
///
/// </summary>
public int Property { get; set; }
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
public void Method(object obj) { }
}
In second
/// <summary>
///
/// </summary>
class B
{
/// <summary>
/// Initializes a new instance of the <see cref="B"/> class.
/// </summary>
public B() { }
/// <summary>
/// Gets or sets the property.
/// </summary>
/// <value>
/// The property.
/// </value>
public int Property { get; set; }
/// <summary>
/// Methods the specified obj.
/// </summary>
/// <param name="obj">The obj.</param>
public void Method(object obj) { }
}
Just above your class, method or property, type /// then press return. This will generate the documentation template for you.
Forgot to answer the other part of your question: this is known as XML Documentation Comments and there is a substantial amount of information about this in MSDN.
What you are referring to is called XML documentation or XML-doc.
XML-doc is performed on a class, field, property, event or method using three forward-slashes (///), followed by XML-formatted meta-information about the class or its member.
VS will help you generate and format these comments with built-in IntelliSense support for XML comments, but there is a free tool called GhostDoc that will automatically generate the full XML-doc template, and it's even "smart" enough in some cases to try to guess a basic description for various elements of the documentation.
Here's a basic example of XML documentation:
/// <summary>
/// Defines the behavior of a class following the Repository pattern for data access
/// with basic atomic operation control.
/// </summary>
/// <typeparam name="TRest">An interface derived from IDomainObject that describes domain objects
/// that can be retrieved or saved by this Repository.</typeparam>
public interface IRepository<TRest> : IDisposable where TRest : IDomainObject
{
/// <summary>
/// Begins a new unit of work to be performed atomically by the Repository.
/// </summary>
/// <returns>A token class representing the unit of work.</returns>
IUnitOfWork BeginUnitOfWork();
/// <summary>
/// Commits all work performed under the specified unit of work.
/// </summary>
/// <param name="unitOfWork">The unit of work.</param>
void CommitUnitOfWork(IUnitOfWork unitOfWork);
/// <summary>
/// Rolls back the specified unit of work.
/// </summary>
/// <param name="unitOfWork">The unit of work.</param>
void RollBackUnitOfWork(IUnitOfWork unitOfWork);
/// <summary>
/// Saves the specified domain object to the data source controlled by the repository.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="domainObject">The domain object.</param>
/// <param name="unitOfWork">The unit of work.</param>
void Save<T>(T domainObject, IUnitOfWork unitOfWork) where T : class, TRest;
/// <summary>
/// Begins a Linq query for a specific object type, to be performed against the Repository's data source.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="unitOfWork">The unit of work.</param>
/// <returns>An IQueryable representing the query to be performed.</returns>
IQueryable<T> QueryFor<T>(IUnitOfWork unitOfWork) where T : class, TRest;
/// <summary>
/// Performs the specified Action using a new unit of work, with commits and rollbacks as necessary.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func">The Action to perform. The lambda or named method must accept an IUnitOfWork as a parameter.</param>
/// <param name="commit">if set to <c>true</c>, commit the unit of work.</param>
void PerformInNewUnitOfWork<T>(Action<IUnitOfWork> func, bool commit = false);
/// <summary>
/// Performs the specified Func using a new unit of work, with commits and rollbacks as necessary.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func">The function to evaluate. The lambda or named method must accept an IUnitOfWork as a parameter.</param>
/// <returns>A single object of the generic type, returned by the function.</returns>
/// <param name="commit">if set to <c>true</c>, commit the unit of work.</param>
T PerformInNewUnitOfWork<T>(Func<IUnitOfWork, T> func, bool commit = false) where T : class, TRest;
/// <summary>
/// Performs the specified Func using a new unit of work, with commits and rollbacks as necessary.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func">The Function to evaluate. The lambda or named method must accept an IUnitOfWork as a parameter.</param>
/// <returns>An enumerable set of objects of the generic type, returned by the function.</returns>
/// <param name="commit">if set to <c>true</c>, commit the unit of work.</param>
IEnumerable<T> PerformInNewUnitOfWork<T>(Func<IUnitOfWork, IEnumerable<T>> func, bool commit = false) where T : class, TRest;
/// <summary>
/// Attaches the specified domain object to the current Unit of Work, allowing operations to be performed on it.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="domainObject">The domain object.</param>
/// <param name="unitOfWork">The unit of work.</param>
void Attach<T>(T domainObject, IUnitOfWork unitOfWork) where T : class, TRest;
/// <summary>
/// Detaches the specified domain object to the current Unit of Work.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="domainObject">The domain object.</param>
/// <param name="unitOfWork">The unit of work.</param>
void Detach<T>(T domainObject, IUnitOfWork unitOfWork) where T : class, TRest;
/// <summary>
/// Refreshes the specified collection of persistent elements with the most recent persisted data.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="elements">The list of elements to refresh.</param>
/// <param name="unitOfWork">The Unit of Work under which to perform the operation.</param>
void Refresh<T>(IList<T> elements, IUnitOfWork unitOfWork) where T : class, TRest;
/// <summary>
/// Deletes the specified domain object from the data store.
/// Usually performs a physical delete; logical deletes are most often done through updates.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="domainObject">The domain object to delete.</param>
/// <param name="unitOfWork">The unit of work under which to perform the operation.</param>
void Delete<T>(T domainObject, IUnitOfWork unitOfWork) where T : class, TRest;
}
I am currently using iBATIS.NET for a small application I am building. I like to create concrete Classes for my DAOs instead of using ISqlMapper directly and invoking named SQL statements. I am not using a Dependency Injection container of any sort, so ideally I have my DAOs set up as follows:
public abstract class AbstractDAO
{
/// <summary>
/// SQL Mapper.
/// </summary>
ISqlMapper mapper;
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="mapper"></param>
public AbstractDAO(ISqlMapper mapper)
{
this.mapper = mapper;
}
}
public class NodeDAO : AbstractDAO
{
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="mapper"></param>
public NodeDAO(ISqlMapper mapper) : base(mapper) { }
/// <summary>
/// Insert Node.
/// </summary>
/// <param name="node"></param>
public void InsertNode(Node node)
{
// ... Assume Some Pretty Code.
}
}
public class NodeRevisionDAO : AbstractDAO
{
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="mapper"></param>
public NodeRevisionDAO (ISqlMapper mapper) : base(mapper) { }
/// <summary>
/// Insert Node Revision.
/// </summary>
/// <param name="nodeRevision"></param>
public void InsertNodeRevision(NodeRevision nodeRevision)
{
// ... Assume Some Pretty Code.
}
}
From my main application code, let's say in some form of Business Layer, I would ideally call two insert Methods on the DAOs:
// ... Assume DAOs are Initialized.
nodeDAO.InsertNode(node);
nodeRevisionDAO.InsertNodeRevision(nodeRevision);
I want to make sure both statements are executed as an atomic operation in a transaction so that if either fails, both will be rolled back. But because the ISqlMapper is injected in both DAOs I have no control over the transactions.
What would be the best approach to this problem? Putting it in another way, how can I handle transactions without exposing the ISqlMapper?