Unity Interception - Custom Interception Behaviour

2019-08-07 10:25发布

问题:

I'm using a custom interception behaviour to filter records (filter is based upon who the current user is) however I'm having some difficulty (this is the body of the interceptors Invoke method)

var companies = methodReturn.ReturnValue as IEnumerable<ICompanyId>;
List<string> filter = CompaniesVisibleToUser();

methodReturn.ReturnValue = companies.Where(company =>     
    filter.Contains(company.CompanyId)).ToList();

The CompaniesVisibleToUser provides a string list of company id's that the user is allowed to view.

My problem is the incoming data - companies - will be a IList of various types all of which should implement ICompanyId in order for the data to be filtered on companyId. However, it seems that the cast - as IEnumerable results in the data being returned as this type which causes problems further up the call stack.

How can I perform a filter without changing the return type?

The exception I get is

Unable to cast object of type 'System.Collections.Generic.List1[PTSM.Application.Dtos.ICompanyId]' to type 'System.Collections.Generic.IList1[PTSM.Application.Dtos.EmployeeOverviewDto]'.

The higher caller is

    public IList<ApplicationLayerDtos.EmployeeOverviewDto> GetEmployeesOverview()
    {
        return _appraisalService.GetEmployeesOverview();
    }

If I change the

IEnumerable <ICompanyId> to IEnumerable<EmployeeOverviewDto> it works as expected but obviously this is not what I want as the list being filtered will not always be of that type.

回答1:

When you do the assignment:

methodReturn.ReturnValue = companies.Where(company =>     
filter.Contains(company.CompanyId)).ToList();

You are setting the return value to be the type List<ICompanyId>.

You could change your higher calling function to be:

public IList<ApplicationLayerDtos.ICompanyId> GetEmployeesOverview()
{
    return _appraisalService.GetEmployeesOverview();
}

Or you could change it to something like:

public IList<ApplicationLayerDtos.EmployeeOverviewDto> GetEmployeesOverview()
{
    var result = (List<EmployeeOverviewDto>)_appraisalService.GetEmployeesOverview().Where(x => x.GetType() == typeof(EmployeeOverviewDto)).ToList();

    return result;
}

Both of which should work.