Add typed procedure descriptors and Exec invoker
This commit is contained in:
100
DynamORM/Helpers/DynamicProcedureDescriptor.cs
Normal file
100
DynamORM/Helpers/DynamicProcedureDescriptor.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012-2026, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using DynamORM.Mapper;
|
||||
using DynamORM.Objects;
|
||||
|
||||
namespace DynamORM.Helpers
|
||||
{
|
||||
internal sealed class DynamicProcedureDescriptor
|
||||
{
|
||||
public Type ProcedureType { get; set; }
|
||||
public Type ArgumentsType { get; set; }
|
||||
public Type ResultType { get; set; }
|
||||
public string ProcedureName { get; set; }
|
||||
public string ResultName { get; set; }
|
||||
|
||||
internal static DynamicProcedureDescriptor Resolve(Type procedureType)
|
||||
{
|
||||
if (procedureType == null)
|
||||
throw new ArgumentNullException("procedureType");
|
||||
|
||||
Type current = procedureType;
|
||||
Type argumentsType = null;
|
||||
Type resultType = null;
|
||||
|
||||
while (current != null && current != typeof(object))
|
||||
{
|
||||
if (current.IsGenericType)
|
||||
{
|
||||
Type genericDefinition = current.GetGenericTypeDefinition();
|
||||
Type[] genericArguments = current.GetGenericArguments();
|
||||
|
||||
if (genericDefinition == typeof(Procedure<>) && genericArguments.Length == 1)
|
||||
{
|
||||
argumentsType = genericArguments[0];
|
||||
break;
|
||||
}
|
||||
|
||||
if (genericDefinition == typeof(Procedure<,>) && genericArguments.Length == 2)
|
||||
{
|
||||
argumentsType = genericArguments[0];
|
||||
resultType = genericArguments[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current = current.BaseType;
|
||||
}
|
||||
|
||||
if (argumentsType == null)
|
||||
throw new InvalidOperationException(string.Format("Type '{0}' is not a typed procedure descriptor.", procedureType.FullName));
|
||||
|
||||
if (!typeof(IProcedureParameters).IsAssignableFrom(argumentsType))
|
||||
throw new InvalidOperationException(string.Format("Procedure descriptor '{0}' declares argument type '{1}' that does not implement IProcedureParameters.", procedureType.FullName, argumentsType.FullName));
|
||||
|
||||
ProcedureAttribute attr = procedureType.GetCustomAttributes(typeof(ProcedureAttribute), true)
|
||||
.Cast<ProcedureAttribute>()
|
||||
.FirstOrDefault();
|
||||
|
||||
string name = attr != null && !string.IsNullOrEmpty(attr.Name) ? attr.Name : procedureType.Name;
|
||||
string owner = attr != null ? attr.Owner : null;
|
||||
|
||||
return new DynamicProcedureDescriptor
|
||||
{
|
||||
ProcedureType = procedureType,
|
||||
ArgumentsType = argumentsType,
|
||||
ResultType = resultType,
|
||||
ProcedureName = string.IsNullOrEmpty(owner) ? name : string.Format("{0}.{1}", owner, name),
|
||||
ResultName = name
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user