A library providing abstractions, interfaces, and utilities for building Standard Data Model (SDM) repositories in DataMiner. This package simplifies CRUD operations, enables middleware patterns, and provides extensibility through attributes and exposers.
- Installation
- Core Concepts
- Getting Started
- Repository Interfaces
- Working with SDM Objects
- Middleware Pattern
- Exception Handling
- Examples
Install the package via NuGet:
Install-Package Skyline.DataMiner.Dev.Utils.SDM.AbstractionsOr via .NET CLI:
dotnet add package Skyline.DataMiner.Dev.Utils.SDM.AbstractionsSDM (Standard Data Model) provides a structured approach to managing domain objects in DataMiner. This library offers:
- Repository Pattern: Standard interfaces for CRUD operations
- Middleware Support: Extensible pipeline for cross-cutting concerns (validation, logging, security)
- Type-Safe Filtering: Strongly-typed query capabilities
- Bulk Operations: Efficient handling of multiple entities
- Paging Support: Built-in pagination for large datasets
Create a class that inherits from SdmObject<T>:
using Skyline.DataMiner.SDM;
public class Product : SdmObject<Product>
{
public string Name { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
public Product() : base() { }
public Product(string identifier) : base(identifier) { }
}Implement one or more repository interfaces:
public class ProductRepository : IRepository<Product>
{
public Product Create(Product entity) { /* Implementation */ }
public Product Read(string id) { /* Implementation */ }
public Product Update(Product entity) { /* Implementation */ }
public void Delete(Product entity) { /* Implementation */ }
public PagedResult<Product> ReadPage(PageDescriptor pageDescriptor) { /* Implementation */ }
public long Count(FilterElement<Product> filter) { /* Implementation */ }
}var repository = new ProductRepository();
// Create
var product = new Product { Name = "Widget", Price = 29.99m, Stock = 100 };
var created = repository.Create(product);
// Read
var retrieved = repository
.Read(ProductExposers.Identifier.Equal(created.Identifier))
.First();
// Update
retrieved.Price = 24.99m;
var updated = repository.Update(retrieved);
// Delete
repository.Delete(updated);The library provides granular interfaces for different operations:
ICreatableRepository<T>: Create single entitiesIReadableRepository<T>: Read entities by identifierIUpdatableRepository<T>: Update existing entitiesIDeletableRepository<T>: Delete entities by identifierICountableRepository<T>: Count entities with filters
IPageableRepository<T>: Paginated readsIQueryableRepository<T>: Advanced query supportIBulkRepository<T>: Bulk create, update, delete operations
IRepository<T> combines all basic CRUD operations plus paging and counting.
public interface IRepository<T> :
ICreatableRepository<T>,
IPageableRepository<T>,
IUpdatableRepository<T>,
IDeletableRepository<T>,
ICountableRepository<T>
where T : class
{
}All SDM objects should inherit from SdmObject<T>:
public abstract class SdmObject<T> : ISdmObject<T>, IEquatable<SdmObject<T>>
where T : SdmObject<T>
{
public virtual string Identifier { get; set; }
}Benefits:
- Automatic identifier management
- Built-in equality comparison based on
Identifier - Type-safe self-reference pattern
For referencing other SDM objects without loading them:
public class Order : SdmObject<Order>
{
public SdmObjectReference<Product> ProductReference { get; set; }
}The MiddlewareRepository<T> enables you to wrap repositories with cross-cutting concerns.
Implement middleware interfaces:
public class ValidationMiddleware<T> : ICreatableMiddleware<T> where T : class
{
public T OnCreate(T entity, Func<T, T> next)
{
// Validate before creating
if (!IsValid(entity))
throw new ValidationException("Invalid entity");
return next(entity); // Continue to next middleware or repository
}
}var repository = new ProductRepository();
var middleware = new ValidationMiddleware<Product>();
var wrappedRepo = new MiddlewareRepository<Product>(repository, middleware);
// ValidationMiddleware will execute before repository.Create()
var product = wrappedRepo.Create(new Product { Name = "Test" });ICreatableMiddleware<T>IUpdatableMiddleware<T>IDeletableMiddleware<T>IPageableMiddleware<T>ICountableMiddleware<T>IBulkCreatableMiddleware<T>IBulkUpdatableMiddleware<T>IBulkDeletableMiddleware<T>
Contains both the data and paging metadata:
public interface IPageResult<T> : IReadOnlyList<T>
where T : class
{
int PageNumber { get; }
bool HasNextPage { get; }
}The library provides specific exception types:
SdmException: Base exception for all SDM operationsSdmCrudException: Errors during CRUD operationsSdmBulkCrudException: Errors during bulk operations (includes partial results)
try
{
repository.Create(product);
}
catch (SdmCrudException ex)
{
Console.WriteLine($"CRUD failed: {ex.Message}");
}
catch (SdmException ex)
{
Console.WriteLine($"SDM error: {ex.Message}");
}// Define your entity
public class Product : SdmObject<Product>
{
public string Name { get; set; }
public decimal Price { get; set; }
}
// Create middleware for logging
public class LoggingMiddleware<T> : IRepositoryMiddleware<T> where T : class
{
public T OnCreate(T entity, Func<T, T> next)
{
Console.WriteLine($"Creating {typeof(T).Name}...");
var result = next(entity);
Console.WriteLine($"Created with ID: {(result as ISdmObject)?.Identifier}");
return result;
}
// Implement other middleware methods...
}
// Usage
var baseRepo = new ProductDomRepository();
var middleware = new LoggingMiddleware<Product>();
var repository = new MiddlewareRepository<Product>(baseRepo, middleware);
var product = repository.Create(new Product
{
Name = "Premium Widget",
Price = 99.99m
});var products = new List<Product>
{
new Product { Name = "Item 1", Price = 10m },
new Product { Name = "Item 2", Price = 20m },
new Product { Name = "Item 3", Price = 30m }
};
var bulkRepo = (IBulkRepository<Product>)repository;
var created = bulkRepo.Create(products);var filter = new ANDFilterElement<Product>(
ProductExposers.Price.GreaterThanOrEqual(10),
ProductExposers.Price.LessThanOrEqual(100),
);
var count = repository.Count(filter);
foreach(var page in repository.ReadPaged(filter, 100))
{
Console.WriteLine($"Showing page {page.PageNumber} with {page.Count} of 100 products");
}DataMiner is a transformational platform that provides vendor-independent control and monitoring of devices and services. Out of the box and by design, it addresses key challenges such as security, complexity, multi-cloud, and much more. It has a pronounced open architecture and powerful capabilities enabling users to evolve easily and continuously.
The foundation of DataMiner is its powerful and versatile data acquisition and control layer. With DataMiner, there are no restrictions to what data users can access. Data sources may reside on premises, in the cloud, or in a hybrid setup.
A unique catalog of 7000+ connectors already exists. In addition, you can leverage DataMiner Development Packages to build your own connectors (also known as "protocols" or "drivers").
Note See also: About DataMiner.
At Skyline Communications, we deal in world-class solutions that are deployed by leading companies around the globe. Check out our proven track record and see how we make our customers' lives easier by empowering them to take their operations to the next level.