Repository navigation
3.0.0-480.Beta
Pre-releasev3.0.0
Exceptions from your DAL now reach you unwrapped — read this before upgrading
This is the one change in this release that breaks quietly. Every one of the generic calls on BaseDataAccess
reaches your derived method through Reflection, and Reflection used to wrap anything that method threw in a
TargetInvocationException. That wrapper is gone. Whatever your Get, GetAll, GetPaged,
GetCount, Insert, Update or Delete throws now arrives at the caller as its own type with its
original stack trace intact, and the same is now true of an exception thrown by an entity's parameterless constructor
or by its identifier property setter.
If you wrote a handler that reaches through the wrapper, it will no longer match and your handling will simply stop
running — there is no compiler error and no warning to tell you.
//no longer catches anything - the handler is now dead code
try { dal.Update(company); }
catch (TargetInvocationException ex) { Log(ex.InnerException); }
//catch what your DAL actually throws
try { dal.Update(company); }
catch (SqlException ex) { Log(ex); }Search your solution for TargetInvocationException before you upgrade. If a call site wrapped one of these
methods, that is the code that has to change.
The method convention is now enforced strictly, and enforced before anything is written
The remaining breaking changes all fail loudly on the first call, so they will find you rather than the other way
around.
Parameter matching is now exact. A convention method declared with a base class or interface parameter —
Insert(IBaseEntity item) standing in for every entity type — used to be matched by the Reflection binder and
will no longer be found. Declare the method once per entity type, with that entity type as the parameter.
Declared return types are validated before the method is invoked. GetAll and GetPaged must declare a
type assignable to IList<T>, Get must declare T or a subclass of it, and GetCount,
Update and Delete must declare int. Insert remains unconstrained and may return anything,
including void. Previously a mis-declared Update or Delete ran to completion, wrote to the
database, and only then failed casting its result; that no longer happens.
static convention methods are no longer found. The lookup has always been documented as targeting the public
surface of your DAL, but static methods were incidentally reachable; they are not any more. Make the method a
public instance method.
The obsolete IBaseDataAccess<TIdType> and BaseDataAccess<TIdType>, deprecated back in v2.1.0, have been
removed. The fix is the one the obsolete warning has been suggesting for four minor versions — drop the generic
argument and use IBaseDataAccess / BaseDataAccess.
Target frameworks consolidated
Now targeting netstandard2.0;net48;net8.0;net9.0, replacing net461;net471;net48;net50;net60;net70;net80;net90.
No consumer is stranded: net461 and net471 resolve against netstandard2.0, as do .NET 5, 6 and 7,
all three of which are past end of support.
Fixed
A struct entity silently received a default identifier from Get<T>. The probe entity was boxed at the moment
the identifier was assigned, so the mutation landed on a copy that was then discarded and your Get method
received an entity with an unset key — no exception, just the wrong row or no row. Struct entities now receive the
identifier they were asked for.
GetAll<T> and GetPaged<T> returned null when the derived method declared a return type that was not
an IList<T>, because the result was coerced with as. A wrong return type is now reported as the wiring
error it is.
An identifier property with no set accessor produced a raw ArgumentException from the Reflection layer. It is
now reported as a convention error naming the entity and the property.
A convention method hidden with new bound unpredictably, because the order Reflection returns same-named
methods in is unspecified. The hierarchy is now walked one level at a time, most derived first, so the method
selected is the one a compile-time call against the same type would bind to.
Added
DataAccessConventionException replaces the generic Exception previously thrown for wiring errors, so
these can be caught and filtered distinctly from data errors. It carries the full specification of the convention in
its own documentation — the method name and signature looked for, the visibility required, the return type each one
must declare, and how the identifier property is resolved for Get. If you are writing a class that inherits
BaseDataAccess, read that type first.
Its messages render types the way you wrote them, so a signature reads as (Company, int, int) rather than
(Company, Int32, Int32), and a return type as IList<Company> rather than in namespace-qualified
backtick-arity form.
ProphetsWay.BaseDataAccess.Tests was added — the first automated coverage this library has had, 68 tests
pinning the convention, the dispatch behavior, and every fix listed above.
A note on visibility
The convention has always required a public instance method. That has not changed in this release; it is now stated
in the documentation and covered by tests rather than left to be discovered.
#2.5.0
Added another interface to identify a base "Soft" entity without an ID property
Added an interface that identifies an entity as "Soft" but doesn't have a specific "Id" property, this is meant to be used in
conjunction with many-to-many tables, or a table that has a compound key and neither is a basic "Id" property that should be keyed off of.
v2.4.0
Adding an interface to identify a base "Soft" entity
Added an interface that identifies an entity as "Soft" so that the DAL will not actually delete the record, but set the deleted date and use that date value as the "deleted" flag.
v2.3.0
Updated .Net Framework versions
Updated the target framework to include .Net 7.0, 8.0, and 9.0 and removed support for .Net Core 2.0, 2.1, and 2.2 as they are no longer supported by Microsoft.
v2.2.0
Added Generic CRUD Calls
Added the ability to call Insert, Update, and Delete generically, similar to how Get<\T>(int id) works already.
v2.1.3, v2.1.4
Minor pipeline fixes
No functional changes, just updating how the pipeline triggers and the readme file.
v2.1.2
Updated to support .net 6.0
Updated the pipeline template to be more robust and reusable across many of my other projects. Also updated the build
targets to support .net 6.0
v2.1.0
Rolled up IBaseDataAccess<TIdType>/BaseDataAccess<TIdType> into their base classes
Updated the root base interface/class to include the generic Get method, because it's possible the user would build
a database where most records have an int primary key, but on one large transaction table you'd prefer to use long
and yet in another you'd want to use Guid so you can share the key across contexts. The original implementation
only allowed one type of primary key. Tagged the old methods as Obsolete, but using them will give you a warning, suggestion
includes the note to simply remove the generic assignment.
v2.0.0
Updated to support .net 5.0
Updated a few things, unfortunately it removed a little bit of functionality, so it counts as a major update,
even tho it's really quite a minor update.
- Removed target frameworks that are not longer supported by Microsoft (netcoreapp2.0, netcoreapp2.2, netcoreapp3.0).
- Added target framework for .Net 5.0.
- Added an icon for the package.
- Updated reference to ProphetsWay.Example
v1.1.1
Added support for .Net Framework 4.8 explicitly and updated the changelog to include changes from v1.1.0.
Updated IBaseDataAccessInt and IBaseDataAccessLong to implement the new IBaseDataAccess<T>
created in version v1.1.0 to cut down on duplicate code.
Updated BaseDataAccessInt and BaseDataAccessLong to implement the new BaseDataAccess<T>
created in version v1.1.0 to cut down on duplicate code.
Removed the Example projects and added a submodule pointing to ProphetsWay.Example.
ProphetsWay.Example references a NuGet reference to this project, albeit a slightly older version.
v1.1.0
New Interfaces IBaseIdEntity<T> and IBaseDataAccess<T>
For added functionality/flexibility, I added some code to specify the ID property of your entities, as well as its type.
Then was able to refactor the BaseDataAccess classes to make use of these new features.
Old classes are marked as Obsolete, but are still usable, all changes are backwards compatible.
IBaseIdEntity<T>
Created a new optional interface, IBaseIdEntity, which inherits from IBaseEntity for backwards compatibility
but this new interface will specify a property "Id" that must exist on your entities, and the type of the Id is
specified by the generic passed in. In general its likely to be either int, long, or a Guid.
IBaseDataAccess<T>
Created a new interface to replace the two older options IBaseDataAccessInt and IBaseDataAccessLong.
Now supports Guid id types.
BaseDataAccess<TIdType>
Created a new base abstract class to replace the two older options BaseDataAccessInt and BaseDataAccessLong.
Now supports Guid id types.
v1.0.0
Initial proper release.
Contains all the interfaces and a single abstract base class for implementing a decoupled Data Access Layer (DAL) for your software solution. See the
readme for more information and check out the Example project for a working solution to reference.
Changes:
This list of changes was auto generated.