- Start Visual Studio 2005.
- Choose File->New->Project from the menu.
- In the New Project dialog box, choose either "Visual C#" or "Visual Basic" in the Projects Type List, and choose "Class Library" in the Templates List.
- Type the project name as "SampleStorageCommit" in the Project Name field, and then choose OK. If desired, type a new location for your project or select a directory using the Browse button, and then choose OK.
-
In the "Solution Explorer" window right-click on the "References" folder, and select "Add Reference..." from the context menu. In the "Add Reference" dialog box, select the "Browse" tab and browse to Leadtools for .NET "\LEAD Technologies\LEADTOOLS 16\Bin\DotNet\Win32" folder and select the following DLLS:
[Showing a C# code example]
Leadtools.dllLeadtools.Dicom.dll Leadtools.Dicom.AddIn.dll Microsoft.Practices.Unity
Add the following .NET System DLL:System.Core (.NET 3.5 dll)
Press the OK button to add the above DLLs to the application. - In the "Solution Explorer" window right-click "Class1.cs" and select Rename from the context menu. Type StorageCommitAddIn.cs and press Enter.
-
Open the StorageCommitAddIn.cs file and add the following using statements:
using Leadtools.Dicom; using Leadtools.Dicom.AddIn; using Leadtools.Dicom.AddIn.Interfaces; using Leadtools.Dicom.AddIn.Attributes; using Microsoft.Practices.Unity;
-
Add IProcessNAction to the StorageCommitAddIn class derivation list. Your class should look like the following:
public class StorageCommitAddIn : IProcessNAction { }
-
Add the DicomAddInAttribute to the class declaration. This lets the Service know that the class processes a Dicom message. After adding the attribute the class should look as follows:
[DicomAddInAttribute("Storage Commit AddIn", "1.0.0.0", Description = "Implements Storage Commitment", Author = "")] public class StorageCommitAddIn : IProcessNAction { }
-
Right-click on IProcessNAction and select Implement Interface->Implement Interface from the context menu. Your class should now look as follows:
public class StorageCommitAddIn : IProcessNAction { public DicomCommandStatusType OnNAction(DicomClient Client, byte PresentationId, int MessageID, string AffectedClass, string Instance, int Action, DicomDataSet Request, DicomDataSet Response) { throw new Exception("The method or operation is not implemented."); } #endregion #region IProcessBreak Members public void Break(BreakType type) { throw new Exception("The method or operation is not implemented."); } }
-
To tell the server what we are interested in responding to we need to specify PresentationContextAttributes over the OnNAction method. This will allow the server to build an association for use when a client connects. In order to support the storage commit we need to make sure to attribute the OnNAction method as follows:
[PresentationContext(DicomUidType.StorageCommitmentPushModelClass, DicomUidType.ImplicitVRLittleEndian)] public DicomCommandStatusType OnNAction(DicomClient Client, byte PresentationId, int MessageID, string AffectedClass, string Instance, int Action, DicomDataSet Request, DicomDataSet Response) { throw new Exception("The method or operation is not implemented."); }
- Add the following support properties to the StorageCommitAddIn class:
private IServiceLog _ServiceLog; /// <summary> /// Allows us to perform service logging. /// </summary> /// <value>The service log.</value> [Dependency] public IServiceLog ServiceLog { set { _ServiceLog = value; } } private IDicomRequest _DicomRequest; /// <summary> /// Allows use to send a dicom request from an addin. /// </summary> /// <value>The dicom request.</value> [Dependency] public IDicomRequest DicomRequest { set { _DicomRequest = value; } } private IAETitle _AeTitle; /// <summary> /// Let's get the AE title information. /// </summary> /// <value>The AE title.</value> [Dependency] public IAETitle AeTitle { set { _AeTitle = value; } }
The above code uses the Microsoft Unity Dependency injection to get registered interfaces that implement features required by our addin. For instance, the IDicomRequest interface is implemented by the Leadtools.Dicom.Server.exe.
-
Add code for the IProcessNAction interface. The sample code processes the commit request on a separate thread and responds to the client at a later time.
For a full working sample of a storage commit please refer to the Storage Commit addin installed as part of the LEADTOOLS PACS Framework installation.
Your code should look as follows:
[PresentationContext(DicomUidType.StorageCommitmentPushModelClass, DicomUidType.ImplicitVRLittleEndian)] public DicomCommandStatusType OnNAction(DicomClient Client, byte PresentationId, int MessageID, string AffectedClass, string Instance, int Action, DicomDataSet Request, DicomDataSet Response) { DicomDataSet ds = new DicomDataSet(Client.Server.TemporaryDirectory); // // Copy the dataset. We will be using it in a thread so we need to copy // it so will be available in the thread. // ds.Copy(Request, null, null);
// // Process the commit on a separate thread. This will allow us to immediately // return a notification to the client informing that we have received the // message. result = AsyncHelper.Execute(delegate() { DicomDataSet commitDS = new DicomDataSet(Client.Server.TemporaryDirectory); PresentationContext pc = new PresentationContext(); DicomRequest request = new DicomRequest(Client);
// // At this point we would process the storage commit and build a response // dataset. For a complete example of this refer to the sample storage commit // addin that ships with the LEADTOOLS PACS Framework.
// // Prepare to send our response back to the requesting client // pc.AbstractSyntax = DicomUidType.StorageCommitmentPushModelClass; pc.TransferSyntaxes.Add(DicomUidType.ImplicitVRLittleEndian); request.PresentationContexts.Add(pc); request.RequireMessagePump = true;
request.ReceiveNReportResponse += new ReceiveNReportResponseDelegate(request_ReceiveNReportResponse); request.ConnectType = ConnectType.Conditional;
_DicomRequest.SendNReportRequest(request, PresentationId, 1000, DicomUidType.StorageCommitmentPushModelClass, DicomUidType.StorageCommitmentPushModelInstance,1, commitDS);
});
Response = null; return DicomCommandStatusType.Success; }
void request_ReceiveNReportResponse(DicomRequest request, byte presentationID, int messageID, string affectedClass, string instance, DicomCommandStatusType status, int dicomEvent, DicomDataSet dataSet) { // // _ServiceLog could be null if there is no implementation. The // LEADTOOLS PACS Framework provides a default implementation. // if(_ServiceLog!=null) { _ServiceLog.Info("NReport Response Received: {0}", status); } }
-
Add support for the IProcessBreak interface. This allows the StorageCommit action to be stopped. Add the following code to your StorageCommitAddin class:
private AsyncResult result = null; public void Break(BreakType type) { // // Stop the commit process if we received a request // to stop processing // if (result != null && !result.IsCompleted) result.Cancel(); }
- Build the class library and take the output and put it in the AddIn directory of your previously created server.
- If the server is running stop it. Start the server.
-
For a more realistic implementation of a Storage Commit refer to the storage commit example that ships with the LEADTOOLS PACS Framework installation.